依赖注入:如何在运行时解析多个实例?

时间:2017-04-17 09:34:26

标签: c# design-patterns dependency-injection inversion-of-control ioc-container

我使用Simple Injector进行注射乐趣。

据我所知,我只能在我的bootstrapper项目中注册并解析我的容器。

所以我在我的控制台应用程序中有这个代码:

static void Main(string[] args)
{
    Container container = ComposeRoot();

    var controller = container.GetInstance<IBussinesLogicController>();
    controller.Execute();

    Console.WriteLine("Started");
    Console.ReadLine();
}

private static Container ComposeRoot()
{
    var container = new Container();

    //Bussines Logic controllers.
    container.Register<IBussinesLogicController, BussinesLogicController>(Lifestyle.Singleton);
    container.Register<IStationController, StationController>(Lifestyle.Transient);

    //Data Access controllers.
    container.Register<IDataAccessController, DataAccessController>(Lifestyle.Singleton);
    container.Register<IDirectoryStructureController, DirectoryStructureController>(Lifestyle.Singleton);

    //Shared controllers.
    container.Register<ILogger, LoggerController>(Lifestyle.Singleton);

    container.Verify();

    return container;
}

这将解析我的businesslogic控制器并调用Execute。

现在执行中我想要解析10个IStationController的新实例并将它们添加到列表中。

var stations = new List<IStationController>();
for (int i = 0; i < 10; i++)
{
    //Resolve IStationController here...
    //IStationController station = diContainer.GetInstance<IStationController>();
    //station.StationName = $"Station {i}";
    //stations.Add(station);
}

我如何正确地执行此操作,因为我的Business Logic项目没有并且不允许引用依赖项容器?

我可以通过向容器添加依赖项来轻松解决此问题,但我担心我没有遵循正确的模式。

我的解决方案布局如下:

  • 班级图书馆(DAL)
  • 类库(BLL)&lt; - IBussinesLogicController
  • 班级图书馆(模特)
  • 班级图书馆(记录员)
  • 控制台应用程序(ConsoleApp6)&lt; - ComposeRoot()

请让我知道这个问题的正确方法。

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以注册factory delegate并在课堂上使用它。

按如下方式注册代表:

container.Register<IStationController, StationController>(Lifestyle.Transient);
container.RegisterSingleton<Func<IStationController>>(
    () => container.GetInstance<IStationController>());

并将其注入您的BussinesLogicController构造函数:

public BussinesLogicController (Func<IStationController> stationControllerFacrtory)

你在循环中使用它:

List<IStationController> stations = new List<IStationController>();
for (int i = 0; i < 10; i++)
{
    //Resolve IStationController here...
    IStationController station = this.stationControllerFactory.Invoke();
    station.StationName = $"Station {i}";
    stations.Add(station);
}   

答案 1 :(得分:1)

查看Simple Injector的文档,查看以下link,其中详细介绍了ASP.Net MVC的依赖注入的无缝实现,其中DI框架负责解析运行时的依赖性。我假设您正在使用MVC控制器

粘贴相关代码并自定义:

应用程序启动事件

<div ng-repeat="item in products.body">
<ul>
    <li>{{item}}</li>
</ul>

基本控制器

using System.Web.Mvc;
using SimpleInjector;
using SimpleInjector.Integration.Web.Mvc;

public class Global : System.Web.HttpApplication {

    protected void Application_Start(object sender, EventArgs e) {
        // 1. Create a new Simple Injector container
        var container = new Container();

        // 2. Configure the container (register)
        // See below for more configuration examples
        container.Register<IStationController, StationController>(Lifestyle.Transient);

        // 3. Optionally verify the container's configuration.
        container.Verify();

        // 4. Store the container for use by the application
        DependencyResolver.SetResolver(
            new SimpleInjectorDependencyResolver(container));
    }
}

重要(来自文档):

在MVC的情况下,第五步(解析实例)是MVC框架的责任。对于每个收到的Web请求,MVC框架会将该请求映射到Controller类型,并要求应用程序的IDependencyResolver创建该控制器类型的实例。注册SimpleInjectorDependencyResolver(SimpleInjector.Integration.Web.Mvc.dll的一部分)将确保将创建实例的请求转发到Simple Injector。 Simple Injector将使用其所有嵌套依赖项创建该控制器。