典型的IoC容器的使用 - 将数据传递的路线容器、路线、典型、数据

2023-09-03 02:58:28 作者:[薄荷少女失心疯v]

我最近开始使用的IoC容器的第一次,但我没有受过教育的,使用它的最佳实践。更多specificaly我使用统一在C#.NET项目,我开始使用它,因为它带着棱镜。

I've recently started using an IoC container for the first time, but I'm not educated on the best practices for using it. More specificaly I'm using Unity in a C# .NET project, and I started using it because it came with Prism.

我用的容器来解决顶级的对象,而他们得到正确的注射的对象根据在容器上。不过,我看不到最好的做法显然,当我有一个对象与孩子和孩子的孩子,我从IoC容器一路下跌需要一些数据,但不是在两者之间。你如何组织通常使用IoC容器?

I use the container to resolve the "top level" objects, and they get the correct objects injected based on the container. However, I can't see the best practice clearly when I have an object with children and children's children, and I need some data from the IoC container all the way down, but not in between. How you'd typically organize the use of IoC container?

起初我还以为你会通过容器无处不需要它,而不是从顶层容器中提取所需的数据和传递这些数据。但是,有一次我得到的问题,当我到了该采取其他具体数据,除了注入接口的对象,我想preFER不通过性能或解决对象初始化后,方法注入这些。

Initially I'd think that you'd pass the container everywhere it is needed instead of extracting the needed data from the container on top-level and passing this data on. But then again I get problems when I reach objects which take other specific data in addition to the injected interfaces, and I'd prefer not to inject these through properties or init-methods after resolving the object.

我希望这是很清楚的,但让我们看看一个虚构的(略愚蠢的..)的例子。

I hope this was clear enough, but let's look at a fictional (and slightly stupid..) example.

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(); 
    }
}

那么,这个例子并没有真正多大意义,但本质是一样的东西,我需要做的。我有一些应用程序命令我传下了线,通过我的视图模型类,因为他们中的一些需要能够触发命令显示的东西。我也有通用的存储等,这些可能需要一些类,但目前正在通过并存储在中产阶级。由于只有命令它,如果你存储的命令或容器没有什么大不了的,但总会有一个典型的IOC使用率通过IoC容器代替,并用这个来解决对象的路线?又是怎么回事,如客户名称的具体数据?你不能仅仅通过这对解决(),所以你需要事后注入呢?

So, this example doesn't really make much sense, but the essence is the same of what I need to do. I have some application commands I pass down the line through my ViewModel classes, because some of them need to be able to trigger commands to display something. I also have common storage, etc. which may be needed for some classes but currently are passed through and stored in middle classes. With only commands it's no big deal if you store commands or container, but would one in a typical IoC-usage pass the IoC container instead, and use this for resolving objects down the line? And what about specific data like the customer name? You can't just pass this in on the Resolve(), so you need to inject that afterwards?

对不起 - 这是短,因为我是能够做到这一点。不需要相同的长度;-)的答案..只是,什么是做这样的东西与IOC容器的最佳做法?

Sorry - this was as short as I was able to make it. Won't require answers of the same length ;-) .. Just; what's the best practice of doing stuff like this with IoC containers?

推荐答案

我不太确定我明白你的问题。但是,我不认为你应该过的容器周围所有。这是很容易只创建一个包装类的容器。例如:

I'm not quite sure that I understand your question. But I don't think you should be passing the container around at all. It's much easier to just create a wrapper class for the container. For example:

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;
    }
  }
}

现在你在code调用这个无处不在。

Now you call this everywhere in your code.

IoCContainer.Instance.Resolve<IAwesomeService>(); 

这是否帮助你?

Does this help you?