配置& # 39;深# 39;依赖于Unity的IoC
本文关键字:IoC Unity 依赖于 配置 | 更新日期: 2023-09-27 18:10:34
假设我在MVC 2项目中有以下类和接口:
存储库:
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;
}
...
}
控制器:
public class Controller1 : Controller
{
private Service1 srv1;
private Service2 srv2;
public Controller1(Service1 srv1, Service2 srv2)
{
this.srv1 = srv1;
this.srv2 = srv2;
}
...
}
我有自定义的ControllerFactory,我知道如何将具体的存储库绑定到接口:
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->Service->Repository,并避免在控制器或服务中调用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使用无参数构造函数。如果您用InjectionConstructorAttribute
标记构造函数(在本例中为public Service()
),则可以收到相同的行为。
当然是以下-
container.RegisterType<Service1>(new TransientLifetimeManager(), new InjectionConstructor());
和Service2
相同。IoC容器将为您构造对象