假设我的 MVC 2 项目中有以下类和接口(interface):
存储库:
IRepository1、IRepository2、IRepository3
public class ConcreteRepository1 : IRepository1
{
public ConcreteRepository1()
{
...
}
...
}
public class ConcreteRepository2 : IRepository2
{
public ConcreteRepository2()
{
...
}
...
}
public class ConcreteRepository3 : IRepository3
{
public ConcreteRepository3()
{
...
}
...
}
服务类别:
public class Service1
{
private IRepository1 repo1;
private IRepository2 repo2;
public Service1(IRepository1 repo1, IRepository2 repo2)
{
this.repo1 = repo1;
this.repo2 = repo2;
}
...
}
Controller :
public class Controller1 : Controller
{
private Service1 srv1;
private Service2 srv2;
public Controller1(Service1 srv1, Service2 srv2)
{
this.srv1 = srv1;
this.srv2 = srv2;
}
...
}
我有自定义 ControllerFactory,我知道如何将具体存储库绑定(bind)到接口(interface):
IUnityContainer container = new UnityContainer();
container.RegisterType<IRepository1, ConcreteRepository1>(new TransientLifetimeManager(), new InjectionConstructor());
container.RegisterType<IRepository2, ConcreteRepository2>(new TransientLifetimeManager(), new InjectionConstructor());
container.RegisterType<IRepository3, ConcreteRepository3>(new TransientLifetimeManager(), new InjectionConstructor());
问题是我应该如何在我的自定义 ControllerFactory 中注册服务的实例和 Controller 的类型以使统一容器解析整个层次结构 Controller->Service->Repository 并避免在 Controller 或服务中调用 Resolve?
谢谢。
最佳答案
如果您已经注册IRepository1-3
, 所以你可以得到 Service1
实例简单调用
container.Resolve<Service1>()
调用 container.Resolve<Controller1>()
将自动解析依赖关系并创建 Controller1
类型的实例.
示例:
public interface IRepository1 { }
public interface IRepository2 { }
public interface IRepository3 { }
public class ConcreteRepository1 : IRepository1 { }
public class ConcreteRepository2 : IRepository2 { }
public class ConcreteRepository3 : IRepository3 { }
public class Service1
{
private IRepository1 repo1;
private IRepository2 repo2;
public Service1(IRepository1 repo1, IRepository2 repo2)
{
this.repo1 = repo1;
this.repo2 = repo2;
}
}
public class Service2
{
private IRepository1 repo1;
private IRepository2 repo2;
public Service2(IRepository1 repo1, IRepository3 repo3)
{
this.repo1 = repo1;
this.repo2 = repo2;
}
}
public class Controller1
{
private Service1 srv1;
private Service2 srv2;
public Controller1(Service1 srv1, Service2 srv2)
{
this.srv1 = srv1;
this.srv2 = srv2;
}
}
正在解决:
var container = new UnityContainer();
container.RegisterType<IRepository1, ConcreteRepository1>();
container.RegisterType<IRepository2, ConcreteRepository2>();
container.RegisterType<IRepository3, ConcreteRepository3>();
var controller = container.Resolve<Controller1>();
编辑:
public interface IRepository { }
public class Repository : IRepository { }
public class Service
{
//[InjectionConstructor]
public Service()
{
Console.WriteLine("Parameterless constructor called");
}
public Service(IRepository repository)
{
Console.WriteLine("Contructor with IRepository called");
}
}
private static void Main()
{
var container = new UnityContainer();
container.RegisterType<IRepository, Repository>();
var service = container.Resolve<Service>();
container.RegisterType<Service>(new InjectionConstructor());
var service2 = container.Resolve<Service>();
}
输出:
Contructor with IRepository called
Parameterless constructor called
所以,当我们还没有注册时Service
(换句话说,它具有默认解析行为),Unity 构造 Service
默认使用最贪婪的构造函数。当您指定 new InjectionConstructor()
,这告诉 Unity 使用无参数构造函数。如果将构造函数(在本例中为 public Service()
)标记为 InjectionConstructorAttribute
,则可以收到相同的行为。 .
关于c# - 使用 Unity IoC 配置 'deep' 依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7647923/