I'm about to embark on a new project using Windsor, but I've been wondering about running into scenarios where a Class A might need to instantiate Class B, but it's not feasible or possible for Windsor to inject an instance of Class B into it. I'm struggling to think of a scenario, but here goes:
Say I have a business entity "Customer" that gets passed to a WCF service. This class has an Ent.Lib self-validation method, which in turn uses a helper class "CustomerValidator". The Customer object received by the service has been deserialized by WCF, so Windsor plays no part in its instantiation, so I can't inject any dependencies. Nor can I pass my CustomerValidator to the self-validation method as it must follow a particular signature for Ent.Lib. So how could I instantiate the CustomerValidator within this class/method? I still want to utilise Windsor rather than simply doing a "var cv = new CustomerValidator();".
It's not a great example as it could be solved in different ways, e.g. passing the Customer object to a validation method rather than having the validation method in the Customer class, but it offers a possible scenario for discussion.
I could expose my WindsorContainer as a public singleton, accessible by any code that needs it, but that seems to be frowned upon. Any other suggestions?
should I reference the container from other classes?
No. By referencing the container, you add complicated and unnecessary dependency to your class which will complicate testing and increase complexity.
The Customer object received by the service has been deserialized by WCF, so Windsor plays no part in its instantiation, so I can't inject any dependencies.
I think this is the direction you should go, try to explore if there really isn't any way to take control of deserialization so you can inject dependencies.
If that fails, consider using http://commonservicelocator.codeplex.com/. Its Microsoft's service location implementation with Windsor adapter available. It's basically the same pattern as if you referenced the container but you don't introduce dependency on specific container implementation. Also I think it will be easier to mock for testing.
Related
Using castle windsor and the LoggingFacility, how would you resolve once and be able to use your logger across your application?
I understand that bootstrapping/installing is done in global.asax and that is where the resolve should be done but I am confused about how you would access your logger outside of global.asax.
The purpose of using Castle Windsor is to follow the Inversion of Control pattern, whereby you allow the container to inject dependencies (like the ILogger) into classes that require them. You "access the logger" by having your controllers (or whatever classes need to do logging) depend on ILogger, either by taking it as a constructor parameter, or by exposing a settable property of type ILogger.
I'd like to be able to register some types on a container and then top these up with some additional type declared in an XML configuration file. Unfortunately, IConfigurationInterpreter (implemented by XmlInterpreter) is only available in the WindsorContainer() constructor, not in any AddXXX() methods. Is there any other way I can achieve this without resorting to parent/child containers (that may soon be unsupported).
Background: Our large application is only starting to use the Castle framework to register and resolve some of it's components. Because Castle is being retrofitted into this app we're using a singleton class to maintain a global instance of WindsorContainer(). In unit tests, we need to wire up this container instance to use a combination of custom mock implementations (specific to the test) + some default mock implementations. For DLL dependency reasons, these mock class types are unavailable in this unit test fixture abstract base class so dynamic registration (using strings) is necessary. I was hoping to use an XML resource file to register the default mocks. Otherwise I have to do the same using an IWindsorInstaller implementation that's really duplicating what XmlInterpreter does. This API appears to be forcing this direction.
I think these will work ...
container.Install(Castle.Windsor.Installer.Configuration.FromXml(resource))
OR
container.Install(Castle.Windsor.Installer.Configuration.FromXmlFile(path))
which both avoid use of the IConfigurationInterpreter interface.
I am developing an AS3 application which uses a Singleton class to store Metrics in Arrays. It's a Singleton because I only ever want one instance of this class to be created and it needs to be created from any part of the app.
The difficulty comes when I want to unit test this class. I thought adding public getters and setters would enable me to unit test this properly and would be useful for my app. I have read that changing to a Factory pattern will enable unit testing or using Inversion of control. This would of course make it more flexible too. I would like to know of people's thoughts on this matter as there are SO many conflicting opinions on this!
Thanks
Chris
If you're using an IoC framework, then make your consumers require an instance of the service in their constructor, and configure the IoC framework to only build one instance and keep handing it out to all requests in the entire application. This is the default behavior of Castle Windsor in my experience.
For unit testing you can use a Mock object in place of the real object.
I am currently making the move from StructureMap to Castle Windsor.
Using StructureMap, you can bootstrap the framework in one central location, and then call ObjectFactory.GetInstance anywhere in your code to grab an instance using that configuration. So conceptually there is a single container that you configure, and calls to the ObjectFactory use that container.
In the tutorials I've seen for Windsor, the container instance is always created explicitly, and resolution happens via the instance of that container. Is this just a difference in approaches between the two frameworks?
Assuming that's the case, what is the recommended way of handling cases where resolution needs to happen separately from configuration?
(Ideally, a single Resolve() call can be made after the configuration code, and no other references to the container will exist; however, there ARE cases where this isn't possible, like when working with a legacy codebase.)
No, it does not. And will not. If you're coming from Structure Map to Castle Windsor, read this.
re: how to pull at a later point w/o static locator see this.
I am not familiar with Windsor, but if it does not already have its own static facade class, it should be trivial to create your own. Create a static class with a static property that holds the configured container. Add a static method that resolves instances from that container. That is exactly what ObjectFactory does. StructureMap has a Container object that does all the real work - ObjectFactory is just a convenience wrapper.
If you really really need this, use CommonServiceLocator. It has adapters to all major IoC containers.
I'm using AutoMapper to map domain entities to view models in an Asp.Net MVC app. I register these mapping classes in Castle Windsor so they are available to the controller thru ctor dependency injection. These mapping classes has a virtual CreateMap method where I can override AutoMapper's mapping, telling it how to map fields from the entity to the view model, which fields to ignore, pointing to methods that transforms the data, etc. All of this is working well; big kudos to the people behind AutoMapper!
So far I've been registering the mapping classes with a Singleton lifestyle in Windsor, but one of them needs to use the IAuthorizationRepository from Rhino.Security which needs to have its components registered as Transient. This forces me to register the mapping classes also as transient, because a singleton mapping class holding a reference to a transient IAuthorizationRepository causes problems the second time the mapper is used (i.e., ISession is already closed errors).
Is it a waste of resources to register all of these mapping classes with a Transient lifestyle, which will cause the mapping class to be instantiated and the CreateMap method to run each time the system wants to map a domain entity to a view model?
Or should I try to find a way to separate the IAuthorizationRepository from the mapping class so I can keep the mapping classes as Singletons?
Thanks
Dan
Another way around it is using the TypedFactoryFacility, then instead of injecting IAuthorizationRepository into your singletons you can inject Func<IAuthorizationRepository>