I am very new to concept of IOC and I understand the fact that they help us resolve different classes in different contexts. Your calling class will just interact with Interface and Interface with decide which implementation to give you and it takes care of newing up the object.
Please do correct me if I am understanding is wrong because my question is based on that:
Now, I see this pattern very often in these projects:
private readonly IEmailService emailService;
private readonly ITemplateRenderer templateRenderer;
private readonly IHtmlToTextTransformer htmlToTextTransformer;
public TemplateEmailService(IEmailService emailService,
ITemplateRenderer templateRenderer,
IHtmlToTextTransformer htmlToTextTransformer)
{
this.emailService = emailService;
this.htmlToTextTransformer = htmlToTextTransformer;
this.templateRenderer = templateRenderer;
}
I understand that this helps using all the implementations of these classes without newing them up and also you don't have to decide WHICH implementaion to get, your IOC decides it for you, right?
but when I code like this, I do not even touch any IOC congiguration files. And again I am usin git for 2 days only but from all the tutorials that I have read, I was expecting my self to configure something which says "Resolve IParent to Child" class. But it works without me doing anything like it. Is it because there is only one implementaion of these interfaces? and If I do have more than one implementations then and then only I will have to configure resolved explicitly?
The code sample you have is a case of Constructor Injection.
In a traditional code, you would have a parameterless constructor, and in it you would "new-up" your objects like this:
IEmailService emailService = new EmailService();
So your code is explictly controlling which implementation gets assigned to the interface variable.
In IoC using constructor injection, control is inverted, meaning the container is "driving the bus" and is creating your TemplateEmailService object. When it is about to create it, the container looks at your constructor parameters (IEmailService , ITemplateRenderer , etc.) and feeds those objects to your class for use.
The IoC container can be configured so that interface A gets fulfilled by implementation B (or C) explicitly. Each one has a way to do it. Or it could do it by convention (IFoo fulfilled by Foo), or even attributes in classes, whatever.
So to answer your question-- you can explicitly define which implementations get used to fulfill certain interfaces. Got to read the IoC container docs for how to.
One more thing - "when you code like this", you technically don't have to be using an IoC container. In fact, your class should not have a direct reference to the container - it will maximize the reusability, and also allow easy testing. So you would wire-up interfaces to implementation classes elsewhere.
Related
I have a servicereference with a method I need to use in a test.
The servicereference class is defined as:
public class MyServiceReference : Clientbase<IMyServiceReference>, IMyServiceReference
{
public MyServiceReference()
{
}
..... methods is then defined
}
From my testmethod I have tried both
private MyServiceReference myServiceReferenceFake = A.Fake<MyServiceReference>();
// And
private MyServiceReference myServiceReference = new MyServiceReference();
For both of these is crashes in the constructor with the message:
System.InvalidOperationException: Could not find default endpoint element that references contract.
All I need is to have a callto definition from a method in that class.
How can this be solved?
I've no experience with Clientbase, which I assume to be a System.ServiceModel.ClientBase<TChannel>,but I can make some general comments.
Since you tried first to fake a MyServiceReference, I'll assume that you're not testing that class, and you want to use it as a collaborator for the system under test. In that case, your best bet is to try faking IMyServiceReference. interfaces are very easy to fake, since they don't bring along any behaviour or baggage like faking a class does.
If you feel you really need to fake a MyServiceReference, then we have to contend with the fact that FakeItEasy will eventually call MyServiceReference(), which will call ClientBase<IMyServiceReference>(), whose documentation says
Initializes a new instance of the ClientBase<TChannel> class using the default target endpoint from the application configuration file.
Based on the error you reported, I assume that the application configuration file is not found or does not include the configuration required to create a MyServiceReference. The fact that you get the same error when you just try to instantiate a MyServiceReference directly strengthens my belief.
So I think your paths forward are either to try faking IMyServiceReference or to provide the configuration that ClientBase<IMyServiceReference> needs.
I am trying to test my Service class below
#Service
#RequiredArgsConstructor(onConstructor = #__(#Autowired))
public class TaskTemplateService {
#NonNull
TaskTemplateRepository taskTemplateRepository;
public void doStuff() {
List<MyObject> list;
doOtherStuff(list)
}
private void doOtherStuff(List <MyObject>) {
//do stuff
}
}
When I am testing the real TaskTemplate, how can I capture what is passed to doOtherStuff?
You cannot and why would you?
Good testing means to specify the behaviour of a unit's public interface. Private methods ought to be covered via testing this way indirectly. If this is not possible then either you have dead, unreachable code or a design problem and should refactor.
BTW, the technical reason that you cannot mock/stub private methods is that most mocking tools, also the built-in feature of Spock, use dynamic proxies (DP) in order to implement mocking. DP technically are subclasses, but private methods can never be extended or even seen by subclasses or being called by them or from other classes, hence the term "private". Consequently, a mock subclass cannot check interactions with private methods.
How exactly you ought to redesign your class in order to make it testable really depends on why you want to "capture" the method argument, as you say. Do you need to replace it by a mock? Do you need to modify or verify the content of the original object?
If the object has a central meaning and you need to replace or verify it, why not make it injectable instead of creating it as a local variable, hermetically sealing it off from the outside world and making it untestable?
Or maybe in your case you could make the private method protected or package-scoped in order to make it testable. Then at least a mock could be created for it and you could capture the argument or stub the result.
I am mostly speculating here because the answer really depends on what is behind //do stuff, i.e. the very information you are hiding in your sample code.
I know how to add a Bean to a CDI container during AfterBeanDiscovery. My problem is that what I really need to do is the equivalent of adding a new producer method with the equivalent of a particularly qualified parameter.
That is, I'd like to somehow programmatically create several of these:
#Produces
#SomeQualifier("x")
private Foo makeFoo(#SomeQualifier("x") final FooMaker fm) {
return fm.makeFoo();
}
...where the domain over which SomeQualifier's value element ranges is known only at AfterBeanDiscovery time. In other words, some other portable extension has installed two FooMaker instances into the container: FooMaker-qualified-by-#SomeQualifier("x") and FooMaker-qualified-by-#SomeQualifier("y"). Now I need to do the equivalent of making two producer methods to "match" them.
Nonbinding is not an option; I want this resolution to take place at container startup, not at injection time.
I am aware of BeanManager's getProducerFactory method, but the dozens if not hundreds of lines of gymnastics I'd have to go through to add the right qualifier annotation on each AnnotatedParameter "reachable" from the AnnotatedMethod I'd have to create by hand (to avoid generics issues) make me think I'm way off the beaten path here.
Update: So in my extension, I have created a private static method that returns a Foo, and has a FooMaker parameter. I've wrapped this in a hand-tooled AnnotatedMethod that reports SomeQualifier("x") etc. in its getAnnotations() method, and also reports SomeQualifier("x") etc. from its AnnotatedParameter's getAnnotations() method. Then I got a ProducerFactory from the BeanManager and feed that into a new Bean that I create, where I use it to implement the create and destroy methods. Everything compiles and so forth just fine.
(However, Weld (in particular) blows up with this usage, which leads me to think that I'm doing Really Bad Thingsā¢.)
What I need: a class with two parents, which are ContextBoundObject and another class.
Why: I need to access the ContextBoundOject to log the method calls.
Composition works? As of now, no (types are not recognized, among other things).
Are other ways to do this? Yes, but not so automatable and without third-party components (maybe a T4 could do, but I'm no expert).
A more detailed explanation.
I need to extend System classes (some of which have already MarshalByRefObject (which is the parent of ContextBoundObject) for parent, for example ServiceBase and FileSystemWatcher, and some not, for example Exception and Timer) to access some inner workings of the framework, so I can log method calls (for now; in future it may change).
If I use this way I only have to add a class name to the object I want to log, instead of adding the logging calls to every method, but obviously I can't do this:
public class MyService:ServiceBase,ContextBoundObject,IDisposable{
public MyService(){}
public Dispose(){}
}
so one could try the usual solution, interfaces, but then if I call Run as in:
ServiceBase.Run(new MyService());
using a hypotethical interface IServiceBase it wouldn't work, because the type ServiceBase is not castable to IServiceBase -- it doesn't inherit from any interface. The problem is even worse with exceptions: throw only accepts a type descending from Exception.
The reverse, producing a IContextBoundObject interface, doesn't seem to work either: the logging mechanism doesn't work by methods, so I don't need to implement any, just an attribute and some small internal classes (and inheriting from ContextBoundObject, not even from MarshalByRefObject, which the metadata present as practically the same).
From what I see, extending from ContextBoundObject puts the extended class in a Proxy (probably because in this way the method calls use SyncProcessMessage(IMessage) and so can be intercepted and logged), maybe there's a way to do it without inheritance, or maybe there could be pre or post compiling techniques available for surrounding methods with logging calls (like T4 Text Templates), I don't know.
If someone wants to give this a look, I used a customized version of MSTestExtentions in my program to do the logging (of the method calls).
Any ideas are appreciated. There could be the need for more explanations, just ask.
Logging method calls is usually done using attributes to annotate classes or methods for which you want to have logging enabled. This is called Aspect Oriented Programming.
For this to work, you need a software that understands those attributes and post-processes your assembly by adding the necessary code to the methods / classes that have been annotated.
For C# there exists PostSharp. See here for an introduction.
Experimenting with proxies I found a way that apparently logs explicit calls.
Essentially I create a RealProxy like in example in the msdn, then obtain the TransparentProxy and use that as the normal object.
The logging is done in the Invoke method overridden in the customized RealProxy class.
static void Main(){
...
var ServiceClassProxy=new ServiceRealProxy(typeof(AServiceBaseClass),new object[]{/*args*/});
aServiceInstance=(AServiceBaseClass)ServiceClassProxy.GetTransparentProxy();
ServiceBase.Run(aServiceInstance);
...
}
In the proxy class the Invoke will be done like this:
class ServiceRealProxy:RealProxy{
...
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
public override IMessage Invoke(IMessage myIMessage){
// remember to set the "__Uri" property you get in the constructor
...
/* logging before */
myReturnMessage = ChannelServices.SyncDispatchMessage(myIMessage);
/* logging after */
...
return myReturnMessage;
// it could be useful making a switch for all the derived types from IMessage; I see 18 of them, from
// System.Runtime.Remoting.Messaging.ConstructionCall
// ... to
// System.Runtime.Remoting.Messaging.TransitionCall
}
...
}
I have still to investigate extensively, but the logging happened. This isn't an answer to my original problem because I have still to test this on classes that don't inherit from MarshalByRefObject.
I have a question that keeps bothering me. Currently, I have started using Kohana 3.2 Framework. I've written a helper to handle some functionality - I have a number of methods, which are (as it should be) declared STATIC. But, all of these methods are somehow working with the database, so I need to load a model. Currently, every method has a non-static variable like this:
$comment = new Model_Comments;
$comment->addComment("abc");
OK, it seems to be working, but then I wanted to get rid of this redundancy by using class attribute to hold the instance of the model (with is class as well).
Something like this:
private static $comment; // Declaring attribute
self::$comment = new Model_Comment; // This is done within helper __constuct method
self::$comment->addComment("abc"); // And call it within the method.
But, I got failed with: Call to a member function addComment() on a non-object
Question is: is it possible to do it ? Maybe there are some other approaches ?
Sorry for a long story and, thanks in advice! :P
A static method cannot call a non-static method without operating on an instance of the class. So, what you're proposing won't work. There may be a way do accomplish something similar, but what about trying the following:
You could implement the singleton or factory pattern for your "helper" class. Then, you could create the model (as an attribute) as you instantiate/return the instance. With an actual instance of your "helper" class, you won't have to worry about the static scope issues.
In other words, you can create a helper-like class as a "normal" class in your application that, upon creation, always has the necessary model available.
I'd be happy to help further if this approach makes sense.
David