我最近开始使用 国际奥委会 第一次使用容器,但我没有接受过使用它的最佳实践的教育。更具体地说我正在使用 统一 在一个 C# .NET 项目中,我开始使用它,因为它附带 棱镜.

我使用容器来解析“顶级”对象,并且它们根据容器获得注入的正确对象。但是,当我有一个带有子对象和子对象的对象的对象时,我无法清楚地看到最佳实践,并且我需要从 IoC 容器一直向下而不是中间的一些数据。您通常如何组织 IoC 容器的使用?

最初,我认为您应该将容器传递到需要的任何地方,而不是从顶层容器中提取所需的数据并传递这些数据。但话又说回来,当我到达除了注入的接口之外还采用其他特定数据的对象时,我会再次遇到问题,并且我不希望在解析对象后通过属性或初始化方法注入这些数据。

我希望这已经足够清楚了,但是让我们看一个虚构的(并且有点愚蠢......)的例子。

class Employee
{
    private ICommands _commands; 
    priate List<Customer> _customers = new List<Customer>(); 
    public Employee(ICommands commands)
    {
        _commands = commands; 
    }
    public void AddCustomer(string customerName)
    {
        var customer = new Customer(customerName, _commands); 
        _customers.Add(customer); 
    }
}

class Customer 
{
    private string _name; 
    private ICommands _commands; 
    priate List<Case> _cases = new List<Case>(); 
    public Customer(string, name, ICommands commands)
    {
        _name = name; 
        _commands = commands; 
    }
    public void AddCase()
    {
        var case = new Case(_commands); 
        _cases.Add(case); 
    }
}

class Case    {
    private ICommands _commands; 
    public Customer(ICommands commands)
    {
        _commands = commands; 
    }
    public void TriggerCommands()
    {
        _command.TriggerSomething(); 
    }
}

所以,这个例子并没有多大意义,但本质与我需要做的事情是一样的。我有一些应用程序命令通过 ViewModel 类向下传递,因为其中一些命令需要能够触发命令来显示某些内容。我也有公共存储等。某些类可能需要它,但目前已传递并存储在中间类中。仅使用命令,如果您存储命令或容器,这没什么大不了的,但是在典型的 IoC 使用中,是否会传递 IoC 容器,并使用它来解析对象?那么诸如客户姓名之类的特定数据呢?您不能只将其传递给 Resolve(),因此您需要随后注入它?

抱歉——这是我能写的最短的了。不需要相同长度的答案;-) ..只是;使用 IoC 容器执行此类操作的最佳实践是什么?

有帮助吗?

解决方案

我不太清楚我理解你的问题。但我认为你根本不应该把容器转过来。为容器创建一个包装类要容易得多。例如:

public class IoCContainer
{
  private static ContainerType = null;

  public static ContainerType Instance 
  {
    get 
    {
      if (_container == null)
      {
        string configFileName = ConfigurationManager.AppSettings[ConfigFileAppSettingName];
        _container = new WindsorContainer(new XmlInterpreter(configFileName));
      }

      return _container;
    }
  }
}

现在,您可以在代码中随处调用它。

IoCContainer.Instance.Resolve<IAwesomeService>(); 

这对你有帮助吗?

其他提示

我不确定这是否能回答您的问题,但我想说,使用 Unity 容器(我认为也适用于其他 IoC 引擎)对应用程序进行操作的一个好方法是:

  • 设计您的课程,以便在构造函数中指定所有所需的依赖项。这样,除非您需要创建新对象,否则您无需明确处理Unity。
  • 如果您需要在类中创建新对象,请在构造函数中传递统一容器本身(作为引用IUnityContainer),并通过使用 Resolve方法。即使对于未注册且未依赖的对象,容器也会为您提供适当的实例,以后您可以决定在不更改客户端代码的情况下注册以前未注册的类型。
  • 至于将显式值传递给解析的对象,您可以在注册类型时指定具体的注入成员(请参阅 InjectionMembers 中的参数 RegisterType 班级)。

您似乎需要为实体声明工厂。通过构造函数注入解析工厂并通过Create方法传递数据值。必须通过工厂的构造函数解析所有其他依赖项。

请参阅这个答案。

我定义了一个静态类IoC,可以使用特定容器进行初始化,并实现Resolve,Resolve(...)等方法,然后将实际工作委托给容器实例(你将存储它)在一个领域或财产中的实例)。这样你就不必传递任何东西,只需使用

即可
IoC.Resolve<SomeType>();

代码中的任何位置。

关于特定数据:某些容器将根据此参数获取参数并解析(Autofac具有此类功能)。或者,您始终可以创建一个工厂类,该工厂类将具有接受一组参数(如客户名称)的方法,并返回相应的对象实例。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top