【问题标题】:Unity child container HierarchicalLifetimeManager mvc and windows serviceunity 子容器 HierarchicalLifetimeManager mvc 和 windows 服务
【发布时间】:2017-04-10 16:00:40
【问题描述】:

我的业务层级别有以下课程(简化代码):

public class StatusUpdater : IStatusUpdater
{
   private readonly IStatusRepo _statusRepo;

   public class StatusUpdater(IStatusRepo statusRepo)
   {
      _statusRepo = statusRepo;
   }

   public voic UpdateStatus(int id, string newStatus)
   {
      _statusRepo.UpdateStatus(id,newStatus);
   }
}

所以目前在 MVC 方面,我使用 PerRequestLifetimeManager 来控制 DbContext 的生命周期。

但是现在在windows服务中我不能使用它,所以我打算做以下,但是感觉不对,因为它看起来很像ServiceLocator

using(var container = ConfiguredContainer.CreateChildContainer())
{
   var statusUpdater = container.Resolve<IStatusUpdater>();
   statusUpdater.UpdateStatus("test");
}

还有其他选择吗?有没有办法在 MVC 应用程序和 Windows 服务中使用相同的代码而无需两种类型的注册:

MVC:

container.RegisterType<IStatusRepo, StatusRepo>(new PerRequestLifetimeManager());

Windows 服务:

container.RegisterType<IStatusRepo, StatusRepo>(new HierarchicalLifetimeManager());

【问题讨论】:

  • 不确定Unity 但在其他 DI 框架中,无论如何您都必须为 MVCWin Service 使用不同的注册码。直接调用Resolve 方法总是“有味道”,因为这就是 DI 框架的用途——在需要时解析实例。当我们在代码中调用.Resolve 方法时,这意味着我们很可能做错了什么。我们可以在构造函数中注入实例并更改使用它们的对象的生命范围。

标签: c# asp.net-mvc entity-framework unity-container object-lifetime


【解决方案1】:

我通常在他们自己的程序集中注册我的类型,很可能像你一样,但是当有特定于执行程序集的东西时,我会在该执行程序集的注册中覆盖它。

// In BusinessProcessor
container.RegisterType<IBusinessProcessorA, MyBusinessProcessorA1>();
container.RegisterType<IBusinessProcessorA, MyBusinessProcessorA2>();
container.RegisterType<IBusinessProcessorB, MyBusinessProcessorB1>();

// In DataAccessLayer
container.RegisterType<IRepository, Repository<A>>("A", new HierarchicalLifetimeManager());
container.RegisterType<IRepository, Repository<B>>("B", new HierarchicalLifetimeManager());
container.RegisterType<IRepository, Repository<C>>("C", new HierarchicalLifetimeManager());

// In WindowsService
Register(BusinessProcessor);    // Call to have the BusinessProcessor register it's own things.
Register(DataAccessLayer);      // Call to have the DataAccessLayer register it's own things.
container.RegisterType<IService, MyService>();

// In WebApplication
Register(BusinessProcessor);    // Call to have the BusinessProcessor register it's own things.
Register(DataAccessLayer);      // Call to have the DataAccessLayer register it's own things.
container.RegisterType<IController, MyController>();
container.RegisterType<IRepository, Repository<A>>("A", new PerRequestLifetimeManager());

另一种方法可能是在 DAL 中使用不同的命名注册来注册存储库,并为 BusinessProcessors 这样做,但这意味着您的整个解决方案都知道这一事实,我不会推荐。完全没有。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多