问题
this is partially a duplication of the same question which has not been yet answered. See here: How can I override a component registered in Castle Windsor?
Since I cannot comment or post any answers to an existing questions I created this question again in the hope that somebody knows the answer to a seemingly basic and simple question.
Keep in mind that:
- I do not want to create a new container.
- I do not care if containers should not be used for Unit testing.
- I do not want to use derived containers.
If Castle Windsor is not able to provide this simple functionality, what other container implementation would you recommend?
回答1:
Windsor works with convention that "last registration wins". But, if you have not SPECIFICALLY told it that this component will be overridden, it will throw an exception. So, there are 3 ways to allow existing component to be be overridden:
- Register component with .IsDefault(). This will override existing registration.
- Register component with .IsFallback(). This will allow component to be overridden later.
- Using unique name for component - .Named("NewComponentName").
I personally prefer .IsDefault() and use this shorthand extension in my integration tests:
public static class WindsorContainerExtensions
{
public static void Override<TService>(this IWindsorContainer container, TService instance) where TService : class
{
container.Register(Component.For<TService>().Instance(instance).IsDefault());
}
}
回答2:
I have no knowledge about other containers but Caslte so my answer is about Castle. If you want to replace what you can do is write an extension method to the IWindsorContainer that will remove and then add.
But I think you should rethink a bit your design:
- Why does your class need direct access to the container and try to resolve from it by itself?
- Why are you in need to change your source code for test code? If writing clean Dependency Injection code according to SOLID your tests will really "magically" flow.
Can you please explain more about the design and about the relevant classes?
回答3:
Answering to a second part of the question - what containers support registration overriding.
Ninject.
See Bind()/Unbind() methods.
I tried also Autofac but seems that the registration becomes frozen after it being built. So seems that it may not be also possible with Autofac.
来源:https://stackoverflow.com/questions/37794460/overriding-a-component-registration-in-castle-windsor-which-container-supports