Is it possible to get Windsor to return different implementations of a service based on a seperate parameter?
For example, if I have a User object which has a Role property, I would like to be able to hydrate this object differently according the the value of Role. I would like to use an IUserService to do this, but have the concrete implementation of IUserService determined by the IoC container.
I think that Ninject offers this functionality as "Contextual Binding" but I'm not sure if Windsor offers it without rolling my own resolution logic?
No, it is not possible (yet).
Take a look here and here.
For now take a look at HandlerProvider if it's got what you need.
If not, you may need to use ISubDependencyResolver (which is not very complicated actually).
Related
I have an Castle Windsor interceptor that I want to use for two different interfaces (just call them IOne and ITwo). Similar to this post http://thatextramile.be/blog/2009/07/protecting-your-application-from-remote-problems/ I want the interceptor to be a singleton with respect to the same interface, but be a different instance for each interface. Obviously registering the interceptor as singleton causes the same instance to be reused across all instances of IOne and ITwo. I need the interceptors to behave this way because I need them to preserve state for all calls through that interface, but they need to be distinct from each other.
I've come across lots of possible ways to approach this, but since I'm not an expert on Windsor, what is the preferred way to handle this situation?
Documentation says it's recommended to use the interceptors with transient lifecycle.
Make interceptors transient
It is strongly advised that you always make your interceptors
transient. Since interceptors can intercept multiple components with
various lifestyles it's best if their own lifespan is no longer than
the component they intercept. So unless you have a very good reason
not to, always make them transient.
I suggest refactoring the shared data interaction to another interface then use that as singleton.
An alternative approach is to make the interceptor generic. Then you can specify the interceptor with the generic argument of your interface.
public class MyInterceptor<T> : IInterceptor
{
...
}
Then register like this
container.Register(Component.For<IOne>()
.ImplementedBy<OneImplementation>()
.Interceptors<MyInterceptor<IOne>>());
container.Register(Component.For<ITwo>()
.ImplementedBy<TwoImplementation>()
.Interceptors<MyInterceptor<ITwo>>());
.Net will recognize MyInterceptor<IOne> and MyInterceptor<ITwo> as separate classes, and so Windsor will create different singleton instances for them.
Of course, this only works if you're making the interceptor. If it's in some library that you don't have access to, then your out of luck with this approach.
We are currently using Autofac as our chosen IoC container. All application code in our reusable assemblies must be kept as clean as possible, so we do not want any direct dependencies on Autofac in our core application. The only place where Autofac is permitted is in the composition root / bootstrappers, where components are registered and wired up. Applications rely on dependency injection to create the required object graphs.
As we are keeping our core application container agnostic, it means that we cannot use the Autofac relationship types, such as Owned, in our core application.
I would like to create a factory that returns components that implement IDisposable. As Autofac tracks disposable objects, I believe I have to use a lifetime scope to create a defined unit of work in which components will be disposed once they go out of scope.
According to the Autofac documentation, this can be achieved by taking a dependency on Func<Owned<T>>, however, as stated above, I cannot take a dependency on Owned as it is an Autofac type. At the bottom of this page, it says
The custom relationship types in Autofac don’t force you to bind your application more tightly to Autofac. They give you a programming model for container configuration that is consistent with the way you write other components (vs. having to know a lot of specific container extension points and APIs that also potentially centralise your configuration.)
For example, you can still create a custom ITaskFactory in your core model, but provide an AutofacTaskFactory implementation based on Func<Owned<T>> if that is desirable.
It is this implementation of ITaskFactory that I believe I need to implement, but I cannot find any examples.
I would be very grateful if someone could provide such an example.
Probably the best "real-world" example of this is the Autofac MVC integration mechanism. While it doesn't use Func<Owned<T>> under the covers it does show you how you might be able to implement a non-Autofac-specific mechanism to talk to Autofac under the covers.
In the MVC case, the System.Web.Mvc.IDependencyResolver is the interface and the Autofac.Integration.Mvc.AutofacDependencyResolver is the implementation. When ASP.NET MVC requests a service, it gets it from System.Web.Mvc.DependencyResolver.Current, which returns an IDependencyResolver. At app startup, that singleton gets set to the Autofac implementation.
The same principle could hold for your custom factory. While IDependencyResolver is not specific to the type it returns (it's just GetService<T>()) you could write a type-specific factory interface just as easily.
I have an MVC application with a typical architecture...
ASP.NET MVC Controller -> Person Service -> Person Repository -> Entity Framework DB Context
I am using Castle Windsor and I can see the benefit of using this along with a ControllerFactory to create controller with the right dependencies. Using this approach the Controller gets a Service injected, which in turn knows how to construct the right Repository, which in turn knows the correct DbContext to use.
The windsor config is something like this...
dicontainer = new WindsorContainer();
dicontainer.Register(Component.For<IPersonService>().ImplementedBy<PersonService>());
dicontainer.Register(
Component.For<IPersonRepository>().UsingFactoryMethod(
() => new PersonRepository(new HrContext("connectionString"))));
It this the right way to do it? I don't like the UsingFactoryMethod, but can't think of another way.
Also, what if the Repository needed a dependency (say ILogger) that was not needed by the service layer? Does this mean I have to pass the ILogger into the service layer and not use it. This seems like a poor design. I'd appreciate some pointers here. I have read loads of articles, but not found a concrete example to verify whether I am doing this right. Thanks.
I try to avoid using factory methods (as you mentioned you felt this smelled funny). To avoid this, you could create a database session object that creates a new DbContext. Then your repositories just need to get an instance of IDbSession and use its dbContext property. Then, you can also easily control the scope of the IDbSession object (don't use singleton because it's not thread safe).
I wanted to make that point so that I could make this more important point... Make your constructors take in only objects that are registered in the DI container (no options or configurations in constructors). Options and configurations should be read/writen in classes whose sole purposes it is to read/write those values. If all classes follow this model, then your DI registration becomes easy and classes can just add whatever dependencies they need in their constructors.
If you are trying to use a third party library that has options in constructors, wrap that class in your own class that has an easy to consume constructor and uses a configuration class to read the values needed to pass to the third party library. This design also introduces a layer of abstraction between your code and the third party library which can then be used to more easily swap (or stub) third party libraries when necessary.
I was wondering how far I should take my IoC implementation in terms of loosely coupling my application. I am using constructor injection in my MVC controller but wondered if I should also be resolving all my other dependencies in the controller instead of newing up objects. For example if I was to create a new User object within a controller method would I use?
var user = new User();
var user = myContainer.Resolve<IUser>();
I like the idea of breaking my dependency on User but is that going too far and could possible make my code harder to read?
This is a very good question, when you read and hear about DI it makes sense and this is the next natural conclusion.
First Steven's point is correct you should not pass the container around. If you need to construct IUser on the fly and it needs to be abstract you should rather inject an Abstract Factory.
Sebastian also posted a good link.
I actually wrote about this in an answer I posted here.
The bottom section of the post:
Not every object and dependency needs or should be dependency injected, first consider if what you are using is actually considered a dependency:
What are dependencies?
Application Configuration
System Resources (Clock)
Third Party Libraries
Database
WCF/Network Services
External Systems (File/Email)
Any of the above objects or collaborators can be out of your control and cause side effects and difference in behavior and make it hard to test. These are the times to consider an Abstraction (Class/Interface) and use DI.
What are not dependencies, doesn't really need DI?
List
MemoryStream
Strings/Primitives
Leaf Objects/Dto's
So in your particular case it really depends on what happens when IUser is constructed also whether you actually need to substitute it with different implementations. If this is not the case and User has only simple types with no external dependencies or side effects just new it up.
Consider what happens when you call new User(), look at the graph below, if it causes other objects to be created and looks like something in the graph below consider IoC.
A cascading dependency object graph:
In this example new on the object either requires or creates a whole bunch of other dependencies. It is most likely out of your control what those dependencies are or do.
When your object is a simple dto it doesn't suffer this problem and IoC is likely not so much required.
I've really gotten into the DI/IoC things - it makes some things a lot easier. However, I have a few inherited classes that implement a class with a required parameterless constructor, I thus use a service locator to get what I want:
MyMembershipProivder() : MyMembershipProvider(ServiceLocator.Current.GetInstance<...>){}
MyMembershipProivder(IMemberRepo memberRepo){...}
Works perfect. However, since I'm also using MVC3 DependencyResolver I find myself no other way but to do:
var locator = new NinjectServiceLocator(kernel);
DependencyResolver.SetResolver(locator);
ServiceLocator.SetLocatorProvider(() => locator);
DependencyResolver gets used within the MVC app and the ServiceLocator gets used throughout the various class libraries.
Is this the ideal way to do this? Am I missing something?
Update
In the example above, the class is a custom asp.net mebership provider. The asp.net membership provider factory requires for my custom provider to have a parameterless constructor, forcing me to use the service locator to inject the repository that it uses internally.
You don't need the parameterless constructor, the Dependency Resolver will inject your dependency into the constructor:
MyMembershipProivder(IMemberRepo memberRepo){...}
You can replace the default controller factory (to use parameterless constructors in your controllers):
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
You wont need to replace the default controller factory, see Linkgoron's comment below.
Anyway using the Dependency Resolver for your MVC application and the Service Locator for your class libraries is fine, I think.
Hope this helps.
It seems as if you don't really have a choice, unless you can refactor your application to use DI from the start. So, I guess using custom a Service Locator is your best bet.
Although, if the classes you've "inherited" are the controller classes you can just remove the default constructors and be done with it, as MVC will handle everything for you.
I've never seen the ServiceLocator class, is it this?
EDIT:
As I've said, I don't see that you have any other option for decoupling. Service location is probably your best bet, without introducing too much bloat and complexity.
Stuff that's implemented as something built into the .Net FW you should look for specific solutions like the one presented for the Membership Provider.