假设我的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-&gt; Service-&gt;存储库并避免在控制器或服务中调用Resolve?
感谢。
答案 0 :(得分:2)
如果您已经注册了IRepository1-3
,那么只需致电{/ p>即可获得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
),则可以收到相同的行为。
答案 1 :(得分:0)
肯定只是以下内容 -
container.RegisterType<Service1>(new TransientLifetimeManager(), new InjectionConstructor());
和Service2
相同。 IoC容器将为您构建对象