C# 配置';深';与统一IoC的依赖关系

C# 配置';深';与统一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

假设我的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());
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