【问题标题】:Require dependency per method call from UnityContainer每个来自 UnityContainer 的方法调用都需要依赖项
【发布时间】:2011-09-13 08:08:29
【问题描述】:

所以在我当前的代码中,我正在开发某种通知管理器。

这个想法是我的主要 BL 将在每个方法调用中使用这个通知管理器。因此可能只有一个通知管理器(我猜是单一的)。

当您使用通知管理器时,您可以通过 SMS\Email\Other 发送通知。实际发生的是通知管理器解析了一个“INotificationProvidor”,它也驻留在统一容器中。此解析是按名称完成的,如“SMS”、“Email”、“Other”。

这是一个小代码sn-p:

var notificationProvidor =
    m_Container.Resolve<INotificationProvidor<TResult>>(
        typeOfNotification.ToString());

ResultMessage<TResult> notificationResult = notificationProvidor
    .SendNotification(source, destination, message, subject);

如您所见,通知管理器拥有一个容器实例来解析每个“INotificationProvidor”。

我怎样才能消除在通知管理器中保存容器的需要?有以下限制:

  • 并非所有类型的“INotificationProvidor”(SMS、电子邮件、其他)都可以在容器中注册。
  • 只有一个通知管理器。 (因为使用它的 BL 在申请过程中会处于活动状态,并且会从 DI 接收)

简而言之...解决每个方法调用的依赖关系。 :)

【问题讨论】:

    标签: c# dependencies unity-container ioc-container


    【解决方案1】:

    我建议这样做的唯一方法是使用某种工厂来解析 INotificationProvider 而不是 Unity 容器,无论如何你必须持有对某些东西的引用,这将解决运行时的依赖关系。

    这是工厂的界面:

    interface IProvidersResolver 
    {
        INotificationProvider<TNotification> Resolve<TNotification>();
    }
    

    这就是你可以在NotificationManager中使用它的方式:

    // here you hold the reference to the resolver
    private IProvidersResolver _resolver;
    
    // here you use injected factory to resolve INotificationProvider
    void UseResolver()
    {
        INotificationProvider<SomeNotification> provider = _resolver.Resole<SomeNotification>();
    }
    

    所以你只持有对IProviderResolver(工厂)的引用。这是常见的做法。或者,您可以:

    1. 为每个INotificationProvider&lt;TNotification&gt; 实例化NotificationManager
    2. 将容器的引用传递给NotificationManager

    【讨论】:

      【解决方案2】:

      我会使用Factory pattern。要么用你自己的接口和实现创建你自己的。或者我相信很多IoC框架很聪明,当你尝试解析Func&lt;string, INotificationProvidor&lt;TResult&gt;&gt;时,它们会自己动态创建工厂方法。

      实际的工厂实现可能需要引用容器本身,但此实现不需要成为您项目的一部分。它可以是项目的一部分,对容器的引用没有问题。

      【讨论】:

      • 对于工厂模式总是 +1,虽然我宁愿定义 INotificationProviderFactory 接口而不是使用 Func&lt;string, T&gt; 委托,但这是我个人的偏好。
      • @Steven 这就是我说“或”的原因。但我也更喜欢自定义接口和实现。
      【解决方案3】:

      我认为您可以通过依赖工厂来解决此问题,该工厂将 typeOfNotification 转换为实际的 NotificationProvider 在需要能够基于刺痛获得NotificationPrivider 的类中。工厂类将由容器创建,并将所有可用的通知提供程序注入其构造函数。

      然后您可以让容器在组合根中为您完成所有连接,但让每个方法根据typeOfNotification 的字符串值获取一个NotificationProvider

      【讨论】:

      • 再次,请注意,我需要解决每个方法调用的依赖关系。
      • @Amir 是的,在您的方法中,您会要求工厂为您提供 NotificationProvider 以获取您拥有的 typeOfNotification 字符串。工厂将通过使用已知提供程序的固定列表并返回其中之一的实例,或者通过在应用程序启动时将 NotificationProvider 的所有实现注入其中,或者通过动态进行解析(扫描程序集可能...)
      猜你喜欢
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      • 2019-03-20
      • 2021-07-12
      • 1970-01-01
      • 2020-04-21
      • 1970-01-01
      • 2019-12-25
      相关资源
      最近更新 更多