问题
What I want: Resolve object A, and inside object A, I want use same container to resolve object C:
public static void Work()
{
IUnityContainer con = new UnityContainer();
con.RegisterType<IA, A>();
con.RegisterType<IB, B>();
con.RegisterType<IC, C>();
var a = con.Resolve<IA>();
}
interface IA { }
interface IB { }
interface IC { }
class A : IA
{
public A(IB b, IUnityContainer con)
{
for (int i = 0; i < 10; i++)
{
var c = con.Resolve<IC>();
}
}
}
class B : IB { };
class C : IC { };
Problem: On many sites I see that injecting container is bad idea, but how to be in such situation?
EDIT 1
Service Locator is an anti-pattern. So if it is okay to use Service Locator with IoC Container, why is it okay?
回答1:
You should not pass a direct reference to your class, cause this will make your code dependant on the used IOC container (here UnityContainer) and makes it a little harder for unittests.
If your class A needs multiple instances of C you should define a factory for this case and pass an instance of that factory to your class A. Your real factory can reference the UnityContainer. For unittests you can mock the interface and pass a mocked instance to your class A.
Code for this would look something like this.
public interface IClassICFactory
{
IC CreateInstance();
}
public class ClassICUnityContainerFactory : IClassCFactory
{
private IUnityContainer _container;
public ClassICUnityContainerFactory(IUnityContainer container)
{
_container = container;
}
public IC CreateInstance()
{
return _container.Resolve<C>();
}
}
class A : IA
{
public A(IB b, IClassICFactory factory)
{
for (int i = 0; i < 10; i++)
{
var c = factory.CreateInstance();
}
}
}
回答2:
While technically it works, it's a bit 'containerception' and would lead to huge amounts of confusion. I create static factory classes for containers that deal with this kind of thing. You class instances resolved by the container should just be concerned with what ever they are meant to do, and not further resolving of other instances.
来源:https://stackoverflow.com/questions/40548487/ioc-container-inject-container