.Net核心依赖注入获取两个工厂方法生成的不同实例

时间:2018-05-18 09:12:50

标签: c# dependency-injection .net-core

我有两个静态类,每个类都有一个静态工厂方法。

public static class First
{
 public IMyService Factory()
 {
   return IMyService()
   {
    //configure with Configs
   };
 }
}

public static class Second
{
 public IMyService Factory()
 {
  return IMyService()
  {
   // configure with different Configs
  };
 }
}

以下内容将使提供程序在被要求时返回实例:

   services.AddSingleton(mb =>
            {
                var myService= First.Factory();
                return myService;
            });

当需要获取具有不同配置的实例时,如何调用不同的工厂?

2 个答案:

答案 0 :(得分:1)

如果是一次性决定(应用启动),则应将配置解压缩为依赖:

在appsettings.json中:

"mysettings":{"bla":"val1"}

项目中的某个地方:

public class mysettings { public string bla {get;set; }

在myservice构造函数中:

public myservice(IOptions<mysettings> settings) { ... }

在startup.cs中:

services.Configure<mysettings>(this.Configuration.GetSection("mysettings"));
services.AddSingleton<Imyservice, myservice>();

像这样注入设置,您的服务将使用appsettings.json中指定的那些实例化

如果您需要“直播”使用哪种设置:

public interface IMyServiceFactory{
  IMyService Create(MySettings settings);
}

比将IMyServiceFactory注入要使用IMyService的类,并使用正确的设置在那里进行即时快照。甚至:

public interface IMyServiceFactory{
  IMyService Create1();
  IMyService Create2();
}

在任何情况下,您只需在启动时注册工厂:

services.AddSingleton<IMyServiceFactory, MyServiceFactory>();

答案 1 :(得分:0)

不知何故,您的客户端代码或引导代码需要表达所需的实现类型。您可以通过以下方式实现它:

public Interface IReqeust
{
    // Some code
}

public class HttpRequest : IRequest
{
    // Implementation
}

public class TcpRequest : IRequest
{
    // Implementation
}

一种方法可能是提供多种方法。您仍然可以隐藏配置,但某些实现细节会泄露到您的客户端代码中。

public Interface IRequestFactory
{
    IRequest CreateHttpRequest();

    IRequest CreateTcpRequest();
}

public class RequestFactory : IRequestFactory
{
    // Implementation
}

另一个解决方案是确定建造工厂时所需的内容。

public Interface IRequestFactory
{
    IRequest CreateRequest();
}

public class RequestFactory : IRequestFactory
{
    private IConfigReader configReader;

    public RequestFactory(IConfigReader configReader)
    {
        this.configReader = configReader;
    }

    public IRequest CreateRequest()
    {
        var currentProtocoll = configReader.GetCurrentProtocoll();
        if(currentProtocoll is HTTP)
            return new HttpRequest();
        else
            return new TcpRequest();
    }
}

我不建议你的解决方案有更多的工厂。至少不是你到目前为止写的。