C# 配置';深';与统一IoC的依赖关系
假设我的MVC 2项目中有以下类和接口: 存储库: IRepository1、IRepository2、IRepository3C# 配置';深';与统一IoC的依赖关系,c#,.net,asp.net-mvc,asp.net-mvc-2,inversion-of-control,C#,.net,Asp.net Mvc,Asp.net Mvc 2,Inversion Of Control,假设我的MVC 2项目中有以下类和接口: 存储库: IRepository1、IRepository2、IRepository3 public class ConcreteRepository1 : IRepository1 { public ConcreteRepository1() { ... } ... } public class ConcreteRepository2 : IRepository2 { public
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());
IUnityContainer container=newunitycontainer();
RegisterType(新TransientLifetimeManager(),新InjectionConstructor());
RegisterType(新TransientLifetimeManager(),新InjectionConstructor());
RegisterType(新TransientLifetimeManager(),新InjectionConstructor());
问题是我应该如何在自定义ControllerFactory中注册服务的实例和控制器类型,以使unity容器解析整个层次结构Controller->Service->Repository,并避免在控制器或服务中调用resolve
谢谢。当然就是以下内容-
container.RegisterType<Service1>(new TransientLifetimeManager(), new InjectionConstructor());
container.RegisterType(新的TransientLifetimeManager(),新的InjectionConstructor());
Service2也一样。如果您已经注册了IRepository1-3
,IoC容器将为您构建对象,因此您只需调用
container.Resolve<Service1>()
解决:
var container = new UnityContainer();
container.RegisterType<IRepository1, ConcreteRepository1>();
container.RegisterType<IRepository2, ConcreteRepository2>();
container.RegisterType<IRepository3, ConcreteRepository3>();
var controller = container.Resolve<Controller1>();
因此,当我们没有注册服务
(换句话说,它有默认的解析行为)时,Unity默认使用最贪婪的构造函数构造服务
。当您指定newinjectionconstructor()
时,这会告诉Unity使用无参数构造函数。如果您使用InjectionConstructorAttribute
标记构造函数(在本例中为public Service()
),则会收到相同的行为。为什么您有多个存储库?您访问不同的数据源吗?只是好奇…@Yves M:我的域层中每个聚合根都有一个存储库。我有一个数据源,但假设这种方法支持每个聚合根在它自己的数据源上。我明白了,谢谢。我试图用下面的代码注册所有控制器的类型,当我删除它时,一切都正常了:var controllerTypes=from t in Assembly.getExecutionGassembly().GetTypes(),其中typeof(IController.IsAssignableFrom(t)选择t;foreach(controllerTypes中的类型t){container.RegisterType(t,new TransientLifetimeManager(),new InjectionConstructor());}
所以在本例中,所有服务/控制器类型都会自动注册Unity,对吗?是否有一种方法可以禁用此“自动注册”并逐个或全部手动注册每个类型/实例?@入侵者,当然可以,无需设置任何“禁用自动还原”选项。你发现了什么异常?当我用我对你答案的第一条评论中提供的代码手动注册控制器时,我得到了“没有接受参数()的构造函数。来源:Microsoft.Practices.Unity”exception@Intruder,这是因为您传递的new InjectionConstructor()
没有参数,因此Unity尝试使用无参数构造函数解析Controller
类,正如我所看到的,Controller
构造函数有2个参数。你自己注册类型的主要目的是什么?
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