C# 如何使用IoC容器在不同的地方使用不同的实现

C# 如何使用IoC容器在不同的地方使用不同的实现,c#,.net,castle-windsor,ioc-container,C#,.net,Castle Windsor,Ioc Container,我想知道如何在不同的客户机中使用一个接口的不同实现。下面是一个例子 public interface IRandomIntGenerator { int Generate(); } public class SimpleRandomIntGenerator : IRandomIntGenerator { public int Generate() { return new Random().Next(); } } public class Cr

我想知道如何在不同的客户机中使用一个接口的不同实现。下面是一个例子

public interface IRandomIntGenerator
{
    int Generate();
}

public class SimpleRandomIntGenerator : IRandomIntGenerator
{
    public int Generate()
    {
        return new Random().Next();
    }
}

public class CryptoServiceProviderRandomIntGenerator : IRandomIntGenerator
{
    public int Generate()
    {
        var generator = new RNGCryptoServiceProvider();
        byte[] bytes = new byte[4];
        generator.GetBytes(bytes);
        return BitConverter.ToInt32(bytes, 0);
    }
}
然后我有两个客户端不想知道特定的实现。一个生成登录代码,另一个选择数组的随机项

public class LogInCodeGenerator
{
    private readonly IRandomIntGenerator randomIntGenerator;

    public LogInCodeGenerator(IRandomIntGenerator randomIntGenerator)
    {
        this.randomIntGenerator = randomIntGenerator;
    }

    public string GenerateCode(int length)
    {
        var builder = new StringBuilder(length);
        for (int i = 0; i < length; i++)
            builder.Append(randomIntGenerator.Generate() % 10);
        return builder.ToString();
    }
}

public class RandomArrayItemChoose
{
    private readonly IRandomIntGenerator randomIntGenerator;

    public RandomArrayItemChoose(IRandomIntGenerator randomIntGenerator)
    {
        this.randomIntGenerator = randomIntGenerator;
    }

    public string Choose(string[] arr)
    {
        return arr[randomIntGenerator.Generate() % arr.Length];
    }
}
公共类LogInCodeGenerator
{
专用只读IRandomIntGenerator randomIntGenerator;
公共登录数据生成器(IRandomIntGenerator randomIntGenerator)
{
this.randomIntGenerator=randomIntGenerator;
}
公共字符串生成代码(整数长度)
{
var builder=新的StringBuilder(长度);
for(int i=0;i
我想配置IoC容器,以便它将
SimpleRandomInGenerator
用于
RandomArrayItemChoose
CryptoServiceProviderRandomInGenerator
用于
LogInCodeGenerator


有没有一种方法可以通过任何流行的.NET IoC容器实现这一点?我对温莎城堡特别感兴趣。

您可以命名已注册的实例,然后按其名称访问它们。 在您的例子中,如果我理解了您的问题,那么您希望基于请求已解析实例的类进行不同的注入。 因此,您可以根据请求类的类型名来命名已注册实例

您必须手动
解析
您的实例:

IRandomIntGenerator generator = container.Resolve<IRandomIntGenerator>(GetType().Name);
IRandomIntGenerator=container.Resolve(GetType().Name);
然后我有两个客户不想知道具体的情况 实现

你的设计似乎有些含糊不清。这些客户可能对具体的实现不感兴趣,但您的系统中似乎有某种要求,
LogInCodeGenerator
必须使用加密随机数

由于这是系统安全性的一个要求,因此最好在设计中明确说明这一点。换句话说,您在这里谈论的是两个单独的合同:

interface IRandomIntGenerator { }

interface ICryptographicRandomIntGenerator { }

这不仅使代码的意图更加清晰,而且从设计中消除这种模糊性使DI配置更加简单。

使用Windsor的服务覆盖。请参阅中的“为要使用的依赖项提供组件”一节。

只需显式声明依赖项:

Component.
    For<IRandomIntGenerator>().
    ImplementedBy<SimpleRandomIntGenerator>().
    Named("SimpleRandomIntGenerator"),
Component.
    For<IRandomIntGenerator>().
    ImplementedBy<CryptoServiceProviderRandomIntGenerator>().
    Named("CryptoServiceProviderRandomIntGenerator"),
Component.
    For<RandomArrayItemChoose>().
    DependsOn(Dependency.
        OnComponent("randomIntGenerator", "SimpleRandomIntGenerator")),
Component.
    For<LogInCodeGenerator>().
    DependsOn(Dependency.
        OnComponent("randomIntGenerator", "CryptoServiceProviderRandomIntGenerator")),
组件。
For()。
由()实现。
命名为(“SimplerDomainGenerator”),
组成部分。
For()。
由()实现。
命名为(“CryptoServiceProviderRandomIntGenerator”),
组成部分。
For()。
DependsOn(依赖性)。
OnComponent(“randomIntGenerator”、“SimplerDomainGenerator”),
组成部分。
For()。
DependsOn(依赖性)。
OnComponent(“randomIntGenerator”、“CryptoServiceProviderRandomIntGenerator”),

我最终得到了继承自
irandomingGenerator
的空接口。这只是一个示例。在大多数情况下,接口包含多个方法。然而,我仍然觉得这是一种肮脏的黑客行为。@Kirill:“在大多数情况下,接口包含几个方法。”如果是这样,您可能违反了。