简体   繁体   English

C#Simple Injector返回动态接口类型

[英]C# Simple Injector return dynamic Interface type

I created a couple data provider classes called Provider1 and Provider2, both of which implement an IProvider interface. 我创建了两个名为Provider1和Provider2的数据提供程序类,它们都实现了IProvider接口。 The idea is that the Provider Instance will vary depending on certain conditions so I created a method in order to return the specific implementation of that interface: 这个想法是,提供者实例将根据某些条件而有所不同,因此我创建了一个方法以返回该接口的特定实现:

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

The problem is that both Providers have objects being instantiated via SimpleInjector and I don't want to have to return something like this: 问题在于,两个提供者都具有通过SimpleInjector实例化的对象,而我不想返回以下内容:

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

Here's an example of the Provider using Constructor Injection and the Interface: 这是使用构造函数注入和接口的提供程序的示例:

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 looks similiar to Provider1, but it contains different logic since it's a different Provider. Provider2看起来与Provider1类似,但是它包含不同的逻辑,因为它是不同的Provider。 I was initially trying something like: 我最初尝试的是:

return Activator.CreateInstance<Provider1>();

but this throws an exception that says "no parameterless constructor defined for this object". 但这会引发一个异常,指出“没有为此对象定义无参数构造函数”。 So my question is: how can I return an instance of Provider1 or Provider2 from a method expecting a return type of IProvider while using SimpleInjector? 所以我的问题是:在使用SimpleInjector时,如何从期望返回IProvider的方法中返回Provider1或Provider2的实例? Can I register a the existing Container with this type at runtime or is that frowned upon? 我可以在运行时使用这种类型注册现有容器吗? I'd like to be able to be able to call something like this from a "Client" without the client caring where the data comes from: 我希望能够从“客户端”中调用类似的内容,而无需客户端关心数据的来源:

private IProvider _provider;
return _provider.GetData();

Thanks! 谢谢!

You need a provider factory, which you would register with SimpleInjector. 您需要一个提供程序工厂,您可以在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);
        }
    }
}

Then in your composition root: 然后在您的合成根目录中:

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

You then inject the factory into whatever class needs to get provider instances and let it call the factory. 然后,您将工厂注入任何需要获取提供程序实例的类中,然后将其称为工厂。 The factory will use the dependencies provided by SimpleInjector and pass them along to the providers. 工厂将使用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();
    }
}

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

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