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

C# 我应该使用嵌套类还是IoC容器?,c#,oop,dependency-injection,C#,Oop,Dependency Injection,我有两个类,服务器和客户端。服务器需要在多个线程中实例化客户端,并且客户端有一个需要提供自定义实现的虚拟成员。我的问题是。客户机类应该是服务器类的嵌套类,还是应该使用接口和依赖项注入将自定义实现引入服务器类。现在,客户机类还有许多私有方法,它们提供了一些不应更改的标准逻辑 public class Server { public void DoWork() { for (var i = 0;i < 10; i++) {

我有两个类,服务器和客户端。服务器需要在多个线程中实例化客户端,并且客户端有一个需要提供自定义实现的虚拟成员。我的问题是。客户机类应该是服务器类的嵌套类,还是应该使用接口和依赖项注入将自定义实现引入服务器类。现在,客户机类还有许多私有方法,它们提供了一些不应更改的标准逻辑

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();
    }
}
公共类服务器
{
公共工作
{
对于(变量i=0;i<10;i++)
{
客户端=新客户端();
客户流程(一);
}
}
}
公共类客户端
{
私人无效剂量()
{ 
...
}
//需要重写并提供自定义逻辑
公共虚拟字符串进程(int i)
{
返回i.ToString();
}
}
工作示例:

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));
        }
    }
}
公共接口IClient
{
字符串处理(字符串消息);
}
公共抽象类客户端:IClient
{
公共虚拟字符串进程(字符串消息)
{
返回消息;
}
}
公共类CustomClient:客户端
{
公共CustomClient(){}
公共重写字符串进程(字符串消息)
{
返回string.Format(“自定义客户端:{0}”,消息);
}
}
公共类服务器
{
私人Func createClient;
公共服务器(){}
公共服务器(Func客户端)
{
createClient=client;
}
公共工作
{
对于(变量i=0;i<10;i++)
{
IClient=client=createClient();
进程(string.Format(“client{0}”,i));
}
}
}
测试程序…您可以单步执行,看到它击中客户机

class Program
{
    static void Main(string[] args)
    {
        Func<CustomClient> factory = () => new CustomClient();
        var server = new Server(factory);
        server.DoWork();
    }
}
类程序
{
静态void Main(字符串[]参数)
{
Func factory=()=>new CustomClient();
var服务器=新服务器(工厂);
server.DoWork();
}
}

应该注入依赖项还是修复依赖项的问题有一个简单的答案——提供逻辑的类是要注入的候选对象。另一方面,如果您不打算更改逻辑,那么您可以针对固定类型进行编码,就像您对大多数基类库所做的那样


您所描述的听起来像是DI的一个场景——如果您允许重写客户机类,那么您就假设可以进行更改。DI是同时处理依赖关系和更改的最明显的方法之一。

如果服务器需要创建客户机,我会将工厂方法传递给服务器以供其使用。所以我会选择依赖注入

例如:您可以向
服务器
构造函数传递
Func
,并将其分配给名为
createClient
的私有字段,然后代替

Client client = new Client();
使用

这样,您就可以完全解耦服务器和客户机


我更喜欢使用一个简单的
Func
委托,而不是一个完整的工厂类,因为这样(a)更易于使用,并且(b)更松散地耦合。

如果服务器需要创建一个客户机,我会将工厂方法传递给服务器供其使用。所以我选择依赖注入。您可以将依赖项传递到(SRP),但它不必是启动的接口。所以让我们假设我使用DI。如果客户机类或多或少需要是一个抽象类,那么该如何工作?我会有一个接口,比如说IClient,然后是一个从IClient继承的抽象类,它有它的默认实现。正如我所说的,它有很多私有方法,它们不会改变,只有一个虚拟方法应该改变。我可以对从接口继承的抽象类的子类使用DI吗?>我可以对从接口继承的抽象类的子类使用DI吗?是:您只需要传入一个委托(或工厂类实例),该委托可以在从服务器类调用时创建客户机类的实例。返回类型可以是抽象类型或接口,但是creator的具体实现当然会使用特定的具体类型。因此我认为您应该将其传递给
服务器
构造函数a
Func
,并将其分配给一个名为,
createClient
然后代替
Client-Client=new-Client()
do
IClient client=createClient()是否有理由传递工厂方法或工厂而不仅仅是实例?抽象类客户端必须通过委托工厂继承和实例化,因为服务器类是一个具体的类。我无法创建它的实例,因为客户机类可以通过许多不同的方式实现。
IClient client = createClient();