简体   繁体   English

我应该使用嵌套类还是IoC容器?

[英]Should I use a nested class or an IoC container?

I have two classes, Server and Client. 我有两个类,服务器和客户端。 Server needs to instantiate Client in multiple threads and Client has a virtual member that needs to provide a custom implementation. 服务器需要在多个线程中实例化客户端,并且客户端具有虚拟成员,需要提供自定义实现。 My question is. 我的问题是。 Should the Client class be a nested class of the Server class or should I use an Interface and Dependency Injection to get the custom implementation into the Server class. Client类应该是Server类的嵌套类,还是应该使用接口和依赖注入将自定义实现添加到Server类中。 Now the Client class also has many private methods that provide some standard logic that shouldn't be changed. 现在,Client类还具有许多私有方法,这些私有方法提供了不应更改的一些标准逻辑。

public class Server
{
    public void DoWork()
    {
        for (var i = 0;i < 10; i++)
        {
            Client client = new Client();
            client.Process(i);
        }
    }
}

public class Client
{
    private void doSomething() 
    { 
       ...
    }

    // Needs to be overridden and provide custom logic
    public virtual string Process(int i)
    {
        return i.ToString();
    }
}

Working example: 工作示例:

public interface IClient
{
    string Process(string message);
}

public abstract class Client : IClient
{
    public virtual string Process(string message)
    {
        return message;
    }
}

public class CustomClient : Client
{
    public CustomClient() { }

    public override string Process(string message)
    {
        return string.Format("Custom Client:{0}", message);
    }
}

public class Server
{
    private Func<IClient> createClient;    

    public Server() { }

    public Server(Func<IClient> client)
    {
        createClient = client;
    }

    public void DoWork()
    {
        for (var i = 0; i < 10; i++)
        {
            IClient = client = createClient();
            client.Process(string.Format("Client #{0}", i));
        }
    }
}

Test Program...you would step through to see it hit the CustomClient 测试程序...您将逐步查看它是否到达CustomClient

class Program
{
    static void Main(string[] args)
    {
        Func<CustomClient> factory = () => new CustomClient();
        var server = new Server(factory);
        server.DoWork();
    }
}

The question whether a dependency should be injected or fixed has a simple answer - a class providing logic which is a subject of change is a candidate to be injected. 是否应该注入依赖项或固定依赖项的问题有一个简单的答案-提供更改主题的逻辑的类是要注入的候选对象。 On the other hand, if you don't plan to change the logic, you code against fixed types, as you do with most base class libraries. 另一方面,如果您不打算更改逻辑,则可以像大多数基类库一样针对固定类型进行编码。

What you describe sounds like a scenario for DI - if you allow to override the client class then you assume that changes are possible. 您所描述的内容听起来像是DI的场景-如果您允许覆盖客户端类,则您认为可能进行更改。 DI is one of most obvious ways to handle the dependency and the change in the same time. DI是同时处理依赖关系和更改的最明显的方法之一。

If the Server needs to create a Client, I'd pass a factory method to the Server for it to use. 如果服务器需要创建客户端,则将工厂方法传递给服务器以供其使用。 So I'd go for dependency injection. 所以我去进行依赖注入。

For example: You could pass to the Server constructor a Func<IClient> and assign it to a private field called, say, createClient and then instead of 例如:您可以将一个Func<IClient>传递给Server构造函数,并将其分配给一个名为createClient的私有字段,然后代替

Client client = new Client();

use 采用

IClient client = createClient();

That way you can completely decouple the server and the client. 这样,您就可以完全断开服务器和客户端的耦合。

I prefer using a simple Func delegate rather than a full factory class, since that is (a) easier to use and (b) more loosely coupled. 我更喜欢使用简单的Func委托而不是完整的工厂类,因为(a)更易于使用和(b)松散耦合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM