【问题标题】:C# Simple Injector return dynamic Interface typeC# Simple Injector 返回动态接口类型
【发布时间】:2017-08-15 22:08:53
【问题描述】:

我创建了两个数据提供者类,称为 Provider1 和 Provider2,它们都实现了 IProvider 接口。这个想法是提供者实例会根据某些条件而变化,所以我创建了一个方法来返回该接口的具体实现:

public IProvider GetProvider()
{
    if(*logic*)
    {
        return new Provider1();
    }
    else 
    {
        return new Provider2();
    }
}

问题是两个提供者都有通过 SimpleInjector 实例化的对象,我不想返回这样的东西:

return new Provider1(new Object1(), new Object2());

这是一个使用构造函数注入和接口的 Provider 示例:

public interface IProvider
{
    public object GetData();
}


public class Provider1 : IProvider
{
    private Object1 _object1;
    private Object2 _object2;

    public Provider1(Object1 object1, object2 object2)
    {
        _object1 = object1; 
        _object2 = object2;
    }

    public object GetData()
    {
         *Provider1 specific logic*
    }
}

Provider2 看起来与 Provider1 相似,但它包含不同的逻辑,因为它是不同的 Provider。我最初尝试类似:

return Activator.CreateInstance<Provider1>();

但这会引发一个异常,提示“没有为此对象定义无参数构造函数”。所以我的问题是:如何在使用 SimpleInjector 时从期望返回类型为 IProvider 的方法返回 Provider1 或 Provider2 的实例?我可以在运行时使用这种类型注册一个现有的 Container 还是不赞成?我希望能够从“客户”调用类似这样的东西,而客户无需关心数据的来源:

private IProvider _provider;
return _provider.GetData();

谢谢!

【问题讨论】:

  • 这里重要的问题是:Object1 和Object2 是什么对象?它们是服务(具有行为的类),它们是配置值(具有在应用程序生命周期内不会更改的数据),还是它们是运行时数据,这意味着它们的值可能会根据请求而改变。

标签: c# .net interface simple-injector


【解决方案1】:

您需要一个提供者工厂,您可以在 SimpleInjector 中注册它。

interface IProviderFactory
{
    IProvider GetProvider();
}

class ProviderFactory : IProviderFactory
{
    private readonly Object1 _object1;
    private readonly Object2 _object2;

    public ProviderFactory(Object1 object1, Object2 object2)
    {
        _object1 = object1; //injected
        _object2 = object2; //injected
    }

    public IProvider GetProvider()
    {
        if (*logic*)
        {
            return new Provider1(_object1, _object2);
        }
        else
        {
            return new Provider2(_object1, _object2);
        }
    }
}

然后在你的作文根目录中:

container.Register<IProviderFactory, ProviderFactory>();
container.Register<Object1, Object1>();
container.Register<Object2, Object2>();

然后,您将工厂注入到任何需要获取提供程序实例的类中,并让它调用工厂。工厂将使用 SimpleInjector 提供的依赖项并将它们传递给提供者。

class Example
{
    private readonly IProviderFactory _providerFactory;

    public Example(IProviderFactory providerFactory)
    {
        _providerFactory = providerFactory;  //Injected
    }

    public void MainCode()
    {
        IProvider p = _providerFactory.GetProvider();
        var foo = p.GetDate();
    }
}

【讨论】:

  • 啊,有道理。谢谢!
猜你喜欢
  • 2014-03-21
  • 1970-01-01
  • 2019-05-01
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
相关资源
最近更新 更多