Register types based on base class - castle-windsor

I'm trying to figure out Windsor as an IOC container.
The problem I'm facing right now is to register all of my viewmodels at once.
I've taken a look at the docs and thought that the following code should work.
However, when I check the container afterwards, nothing is registered.
container.Register(Classes.FromThisAssembly()
.BasedOn<ViewModelBase>()
.LifestyleTransient());
where ViewModelBase is my baseclass.
Also tried the following:
container.Register(Classes.FromThisAssembly()
.InSameNamespaceAs<MainWindowViewModel>()
.LifestyleTransient());
The necessary dependencies can be resolved, the viewmodels not.
I suppose I'm missing something obvious here?
Edit
My dependencies are registered as follows:
this.container.Register(Component.For<IDALHandler>().ImplementedBy<DALHandler>());
this.container.Register(Component.For<IBLHandler>().ImplementedBy<BLHandler>());
UPDATE
Since the suggestions didn't work, I was planning on adding the code from my baseclass and viewmodel here.
While doing so I noticed that my viewmodel-class was internal sealed. When changing it to public sealed, the above code did work.
Can someone explain why internal classes can't be registered in the container?
I've already tested other IOC containers with the exact same setup and they didn't complain about it.

Your example of registration started working well in my application when I added selection of the service for component. E.g. .WithService.AllInterfaces()
container.Register(Classes.FromThisAssembly()
.BasedOn(typeof(MyBaseClass<>))
.WithService.AllInterfaces()
.LifestylePerWebRequest()
);
container.Register(Classes.FromThisAssembly()
.InSameNamespaceAs<MyBaseClass>()
.WithService.AllInterfaces()
.LifestylePerWebRequest()
);
UPDATE:
In order to register internal types, .IncludeNonPublicTypes() should be used.
public class ExampleTest
{
[Test]
public void MyBaseClass_Base()
{
var target = new WindsorContainer();
target.Register(Classes.FromThisAssembly()
.IncludeNonPublicTypes()
.BasedOn(typeof(MyBaseClass<>))
.WithService.Base()
//.LifestylePerWebRequest()
);
//assert
target.Resolve<MyBaseClass<int>>().Should().BeOfType<A>();
target.Resolve<MyBaseClass<string>>().Should().BeOfType<B>();
}
[Test]
public void MyBaseClass_Self()
{
var target = new WindsorContainer();
target.Register(Classes.FromThisAssembly()
.IncludeNonPublicTypes()
.BasedOn(typeof(MyBaseClass<>))
.WithService.Self()
//.LifestylePerWebRequest()
);
//assert
target.Resolve<MyBaseClass<int>>().Should().BeOfType<MyBaseClass<int>>();
target.Resolve<MyBaseClass<string>>().Should().BeOfType<MyBaseClass<string>>();
target.Resolve<A>().Should().BeOfType<A>();
target.Resolve<B>().Should().BeOfType<B>();
}
}
internal class MyBaseClass<T>
{
}
internal class A : MyBaseClass<int>
{
}
internal class B : MyBaseClass<string>
{
}

My guess is your viewmodels have been registered in the container, but they are not resolvable through their interface.
Set a breakpoint after the registration and check if container has been filled as expected.
UPDATE as per my comment below:
Keep in mind "group" registration (Classes.) skips internal class.
If they have been registered, let say you have a ViewModel like this
public class MyViewModel1 : ViewModelBase, IMyViewModel1
container.Resolve<MyViewModel1>() // resolve
container.Resolve<IMyViewModel1>() // no resolve
to accomplish the second resolving scenario you have to do what Ilya pointed about about adding WithService during registration, so you can resolve by interface instead of by concrete.

Related

Unable to mock the local variable inside a method in java [duplicate]

I'm using Mockito 1.9.0. I want mock the behaviour for a single method of a class in a JUnit test, so I have
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
The problem is, in the second line, myClassSpy.method1() is actually getting called, resulting in an exception. The only reason I'm using mocks is so that later, whenever myClassSpy.method1() is called, the real method won't be called and the myResults object will be returned.
MyClass is an interface and myInstance is an implementation of that, if that matters.
What do I need to do to correct this spying behaviour?
Let me quote the official documentation:
Important gotcha on spying real objects!
Sometimes it's impossible to use when(Object) for stubbing spies. Example:
List list = new LinkedList();
List spy = spy(list);
// Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
In your case it goes something like:
doReturn(resultsIWant).when(myClassSpy).method1();
In my case, using Mockito 2.0, I had to change all the any() parameters to nullable() in order to stub the real call.
My case was different from the accepted answer. I was trying to mock a package-private method for an instance that did not live in that package
package common;
public class AnimalĀ {
void packageProtected();
}
package instances;
class Dog extends Animal { }
and the test classes
package common;
public abstract class AnimalTest<T extends Animal> {
#Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
#Test
public void myTest(){}
}
The compilation is correct, but when it tries to setup the test, it invokes the real method instead.
Declaring the method protected or public fixes the issue, tho it's not a clean solution.
The answer by Tomasz Nurkiewicz appears not to tell the whole story!
NB Mockito version: 1.10.19.
I am very much a Mockito newb, so can't explain the following behaviour: if there's an expert out there who can improve this answer, please feel free.
The method in question here, getContentStringValue, is NOT final and NOT static.
This line does call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
This line does not call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
For reasons which I can't answer, using isA() causes the intended (?) "do not call method" behaviour of doReturn to fail.
Let's look at the method signatures involved here: they are both static methods of Matchers. Both are said by the Javadoc to return null, which is a little difficult to get your head around in itself. Presumably the Class object passed as the parameter is examined but the result either never calculated or discarded. Given that null can stand for any class and that you are hoping for the mocked method not to be called, couldn't the signatures of isA( ... ) and any( ... ) just return null rather than a generic parameter* <T>?
Anyway:
public static <T> T isA(java.lang.Class<T> clazz)
public static <T> T any(java.lang.Class<T> clazz)
The API documentation does not give any clue about this. It also seems to say the need for such "do not call method" behaviour is "very rare". Personally I use this technique all the time: typically I find that mocking involves a few lines which "set the scene" ... followed by calling a method which then "plays out" the scene in the mock context which you have staged... and while you are setting up the scenery and the props the last thing you want is for the actors to enter stage left and start acting their hearts out...
But this is way beyond my pay grade... I invite explanations from any passing Mockito high priests...
* is "generic parameter" the right term?
One more possible scenario which may causing issues with spies is when you're testing spring beans (with spring test framework) or some other framework that is proxing your objects during test.
Example
#Autowired
private MonitoringDocumentsRepository repository
void test(){
repository = Mockito.spy(repository)
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
In above code both Spring and Mockito will try to proxy your MonitoringDocumentsRepository object, but Spring will be first, which will cause real call of findMonitoringDocuments method. If we debug our code just after putting a spy on repository object it will look like this inside debugger:
repository = MonitoringDocumentsRepository$$EnhancerBySpringCGLIB$$MockitoMock$
#SpyBean to the rescue
If instead #Autowired annotation we use #SpyBean annotation, we will solve above problem, the SpyBean annotation will also inject repository object but it will be firstly proxied by Mockito and will look like this inside debugger
repository = MonitoringDocumentsRepository$$MockitoMock$$EnhancerBySpringCGLIB$
and here is the code:
#SpyBean
private MonitoringDocumentsRepository repository
void test(){
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
Important gotcha on spying real objects
When stubbing a method using spies , please use doReturn() family of methods.
when(Object) would result in calling the actual method that can throw exceptions.
List spy = spy(new LinkedList());
//Incorrect , spy.get() will throw IndexOutOfBoundsException
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
I've found yet another reason for spy to call the original method.
Someone had the idea to mock a final class, and found about MockMaker:
As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line: mock-maker-inline
Source: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
After I merged and brought that file to my machine, my tests failed.
I just had to remove the line (or the file), and spy() worked.
One way to make sure a method from a class is not called is to override the method with a dummy.
WebFormCreatorActivity activity = spy(new WebFormCreatorActivity(clientFactory) {//spy(new WebFormCreatorActivity(clientFactory));
#Override
public void select(TreeItem i) {
log.debug("SELECT");
};
});
As mentioned in some of the comments, my method was "static" (though being called on by an instance of the class)
public class A {
static void myMethod() {...}
}
A instance = spy(new A());
verify(instance).myMethod(); // still calls the original method because it's static
Work around was make an instance method or upgrade Mockito to a newer version with some config: https://stackoverflow.com/a/62860455/32453
Bit late to the party but above solutions did not work for me , so sharing my 0.02$
Mokcito version: 1.10.19
MyClass.java
private int handleAction(List<String> argList, String action)
Test.java
MyClass spy = PowerMockito.spy(new MyClass());
Following did NOT work for me (actual method was being called):
1.
doReturn(0).when(spy , "handleAction", ListUtils.EMPTY_LIST, new String());
2.
doReturn(0).when(spy , "handleAction", any(), anyString());
3.
doReturn(0).when(spy , "handleAction", null, null);
Following WORKED:
doReturn(0).when(spy , "handleAction", any(List.class), anyString());

Castle Windsor - how to resolve by name?

My application uses the "SignalR" client/server comms framework. If you aren't familiar with it, the server-side app typically contains one or more "hub" classes (similar to asmx web services), each providing methods that can be called by a client. During startup, the client needs to first create a connection, then create a "proxy" for each hub that it will need to talk to, e.g.:-
var hubConnection = new HubConnection("http://...");
var fooHubProxy = hubConnection.CreateHubProxy("FooHub");
var barHubProxy = hubConnection.CreateHubProxy("BarHub");
...etc...
The string parameter passed to CreateHubProxy() is the name of the server-side hub class. The method return type is IHubProxy.
It feels like I should be able to utilise Windsor here, but I'm struggling to find a solution. My first thought was to instantiate the hub proxies and register these instances with Windsor (by name), e.g.
var fooHubProxy = hubConnection.CreateHubProxy("FooHub");
container.Register(Component.For<IHubProxy>().Instance(fooHubProxy).LifestyleSingleton().Named("FooHub"));
...etc...
The problem is that when a class needs a hub proxy, the only way to resolve it by name is to use service locator pattern, which isn't recommended. What other Windsor features (e.g. typed factories, etc.) might be useful here?
Edit
I've just found Windsor's .UsingFactoryMethod, and am wondering if this would work, to simplify hub registration:
container.Register(Component.For<IHubProxy>()
.UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub"))
.LifestyleSingleton()
.Named("FooHub"));
I guess I still have the problem of how to resolve by name though.
Two years later, but I have a more elegant solution for other people that stummble accross this problem too.
It is possible to use TypedFactory facility and adapt it to you needs like here.
first create the factory interface (only! no need for the actual implementation, castle will take care of that):
public interface IHubProxyFactory
{
IHubProxy GetProxy(string proxyName);
}
Now we need a class that extend the default typed facotory and retreives the component's name from the input (proxyName):
class NamedTypeFactory : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
string componentName = null;
if (arguments!= null && arguments.Length > 0)
{
componentName = arguments[0] as string;
}
if (string.IsNullOrEmpty(componentName))
componentName = base.GetComponentName(method, arguments);
return componentName;
}
}
And then register the factory with castle and specify that your NamedTypeFactory will be used:
Component.For<IHubProxyFactory>().AsFactory(new NamedTypeFactory())
Now every class can get the factory interface in its constructor:
public class SomeClass
{
private IHubProxy _fooHub;
private IHubProxy _barHub;
public SomeClass(IHubProxyFactory hubProxyFactory)
{
_fooHub = hubProxyFactory.GetProxy("FooHub");
_barHub = hubProxyFactory.GetProxy("BarHub");
}
}
Okay, I think I've found a possible solution, partly using the approach detailed here which shows how it is possible to register Func<>s with Windsor.
First, I register a delegate (Func<>) that uses the container to resolve by name:-
Container.Register(Component.For<Func<string, IHubProxy>>()
.Instance(name => Container.Resolve<IHubProxy>(name))
.LifestyleSingleton());
Think of this as an IHubProxy "factory".
Next, I register my hub proxies as detailed in my original question:-
container.Register(Component.For<IHubProxy>()
.UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub"))
.LifestyleSingleton()
.Named("FooHub"));
container.Register(Component.For<IHubProxy>()
.UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("BarHub"))
.LifestyleSingleton()
.Named("BarHub"));
Here is an example of a class that needs instances of the hub proxies:-
public class SomeClass
{
private IHubProxy _fooHub;
private IHubProxy _barHub;
public SomeClass(Func<string, IHubProxy> hubProxyFactory)
{
_fooHub = hubProxyFactory("FooHub");
_barHub = hubProxyFactory("BarHub");
}
}
Untried so far, but it looks promising. It's a clever solution but injecting the Func<> feels a little hacky, so I would still be keen to hear of other possible solutions to my problem.
I just used a similar method to yours. I use a typed Factory. Advantage is I have type safety for my hubs. Registering the hubs is the same. The rest differs a bit but is technical the same.
IServiceFactory {
IHubProxy GetFooHub();
IHubProxy GetBarHub();
}
And Registration:
Container.AddFacility<TypedFactoryFacility>();
Container.Register(Component.For<IServiceFactory>().AsFactory());
Usage:
public class SomeClass
{
private IHubProxy _fooHub;
private IHubProxy _barHub;
public SomeClass(IServiceFactry hubProxyFactory)
{
_fooHub = hubProxyFactory.GetFooHub();
_barHub = hubProxyFactory.GetBarHub();
}
}
Btw. Factory.Get"Name"() resolves by name.

Can you explain this castle windsor registration?

I am referring to this tutorial.
At the beginning the IController types are registered as:
public class ControllersInstaller:IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.BasedOn<IController>()
.LifestyleTransient());
}
}
But later The EventRepository is registered as below:
public class RepositoriesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.Where(Component.IsInSameNamespaceAs<EventRepository>())
.WithService.DefaultInterfaces()
.LifestyleTransient()));
}
}
What is the difference between the two? I tried using the method used for IController registration to register IEventRepository but it doesn't work? Why?
Now in case of IEventRepository, its implementation EventRepository is used in the registration. If I implement another class say AnotherEventRepository, then I will have to add another registration for that. Can't we use a single registration to register all types of IEventRepository.
If you need to registrer all classes implementing IEventRepository you need to add BasedOn as above. Don't forget the Where you added... That means you are considering only classes belonging to that ns.
The first registration is pretty straightforward. You just register all classes implementing IController interface. Those classes are also they services. So if you want to resolve eg. HomeController you just call container.Resolve<HomeController>().
The second registration takes all classes from the namespace where the EventRepository is declared and registers them with default interfaces. So if you want to resolve EventRepository you have to call container.Resolve<IEventRepository>().
In case of AnotherEventRepository you don't have to add another registration if it is in the same namespace. But if it also implements IEventRepository you won't actually know which implementations will be resolved.

Basic Windsor Constructor Injection

I am new to Windsor and am trying to implement the most basic constructor injection. Apparently the API has changed so much over the recent versions that the documentation that is for the current version seems to assume you already know how to do it, and the documentation for the old versions is outdated.
I have a simple test component:
public class ConstructorInjectedComponent
{
public IMyComponent Component { get; set; }
public ConstructorInjectedComponent(IMyComponent component)
{
Component = component;
}
}
There is a simple implementation of IMyComponent:
public class AMyComponent : IMyComponent
{
public string Name { get; set; }
public AMyComponent()
{
Name = Guid.NewGuid().ToString("N");
}
}
And I want to somehow register my types with Windsor such that I can get back an instance of ConstructorInjectedComponent that contains an instance of its dependency: IMyComponent.
I've register AMyComponent like so:
_container.Register(Component.For(typeof(AMyComponent)));
I've register ConstructorInjectedComponent like this:
_container.Register(Component.For(typeof(ConstructorInjectedComponent)));
and tried to resolve it with
_container.Resolve(typeof(ConstructorInjectedComponent));
But that fails with "can't create component ConstructorInjectedComponent because it has dependencies which need to be satisfied.
so I try to pass in an IDictionary of dependencies for the ConstructorInjectedComponent ... and this is where the documentation fails me.
I have no idea how to define that dictionary. I can find no documentation which explains it. I've tried this:
var d = new Dictionary<string, string>() {{"IMyComponent", "AMyComponent"}};
_container.Register(Component.For(typeof(ConstructorInjectedComponent))
.DependsOn(dependencies));
But that fails with the same "has dependencies that need to be resolved" error.
What am I doing wrong?
First it's crucial to make sure you understand the basic concepts, namely what a component is, what a service is, and what a dependency is.
The documentation about it is quite good.
The documentation about how to use registration API should help you get going.
The tl;dr asnwer is: since ConstructorInjectedComponent depends on IMyComponent make sure you register AMyComponent to expose IMyComponent as a service.
_container.Register(Component.For<IMyComponent>().ImplementedBy<AMyComponent>());

Using Castle Windsor to inject dependencies when the classes inherit from the same base class

I have two classes that inherit from the same base class.
public class UserDetailValidator : BaseValidator<UserDetail>{
public UserDetailValidator(IRepository<Person, Guid> userRepository, AddressValidator addressValidator)
{
RuleFor(x => x.FirstName).Length(1, 10);
}
}
public class AddressValidator : BaseValidator<Address>
When I try and get the UserDetailValidator from WindsorServiceLocator I get the error
Missing dependency.
Component UserDetailValidator has a dependency on AddressValidator, which could not be resolved.
Make sure the dependency is correctly registered in the container as a service, or provided as inline argument. I'm using the following in my ValidationInstaller.
container.Register(
AllTypes.FromAssemblyNamed("Validation")
.IncludeNonPublicTypes()
.BasedOn(typeof(IValidator<>))
.WithService.AllInterfaces()
.LifestyleTransient()
The IRepository component is being injected with no problems. It's only the AddressValidator that does not come in. What am I not doing properly? I'm using Castle Windsor 3.0
I changed the type of the Argument being passed
to UserDetailValidator from AddressValidator to IValidator.
I still have to use AllInterfaces (at least in my testing so far) but
it now works.