gpt4 book ai didi

autofac - 具有运行时构造函数参数的键控委托(delegate)工厂?

转载 作者:行者123 更新时间:2023-12-03 14:59:00 25 4
gpt4 key购买 nike

可以说我有以下服务和组件:

public interface IService
{
void DoWork();
}

public class ServiceA : IService
{
private readonly string _name;

public ServiceA(string name)
{
_name = name;
}

public void DoWork()
{
//ServiceA DoWork implementation
}
}

public class ServiceB : IService
{
private readonly string _name;

public ServiceB(string name)
{
_name = name;
}

public void DoWork()
{
//ServiceB DoWork implementation
}
}

请注意,每个组件都有一个构造函数参数 name .也可以说 name在运行时确定。

我一直在阅读 AutoFac 文档,试图找到一种类型安全的方法来解析这样的组件,而不必直接引用容器。如果我只有一个 IService 的实现那么我可以使用 Delegate Factory将运行时参数传递给构造函数。但是,我有两种实现,应该使用的也必须在运行时确定。如果我没有 name构造函数参数然后我可以 register the two components by Key and the resolve using IIndex

我无法弄清楚如何做到这两点。有没有办法我可以以某种方式结合使用委托(delegate)工厂和 IIndex组件分辨率?还是有另一种方法来注册和解析这两个组件而不必直接引用容器?

最佳答案

正如您所说,AutoFac 原生支持您的两个单独的要求。

  • 可以使用 Parameterized Instantiation 实现构造函数参数的运行时解析
  • 可以使用 Keyed Service Lookup 来实现特定服务实现的解析。

  • 但是,似乎没有直接支持一起使用这两个结构。 IE。以下 不工作 :
    public enum ServiceType
    {
    ServiceA,
    ServiceB
    }

    public class MyComponent
    {
    public MyComponent(Func<string, IIndex<ServiceType, IService> factory)
    {
    var service = factory("some_string")[ServiceType.ServiceA];
    }
    }

    我的解决方法一直是 将服务的解决方案移至每个服务实现的工厂 .然后按如下方式工作:
  • 依赖于特定服务实现的组件接受 AutoFac 工厂委托(delegate),该委托(delegate)解析为特定于所需服务实现的工厂
  • 反过来,服务工厂依赖于 AutoFac 工厂委托(delegate),该委托(delegate)知道如何从服务的(运行时)构造函数参数创建特定的服务实现
  • 这种方法使用 native AutoFac 构造,并且在容器接线之外对 AutoFac 没有任何依赖关系。

  • 这是一个粗略的例子。请注意,多个工厂可以简化为一个通用工厂 - 但为了清楚起见,我将其保留原样:

    服务实现
    public enum ServiceType
    {
    NotSet,
    ServiceA,
    ServiceB
    }

    public interface IService
    {
    string DoWork();
    }

    public class ServiceA : IService
    {
    private readonly string _name;

    public ServiceA(string name)
    {
    _name = name;
    }

    public string DoWork()
    {
    throw new NotImplementedException();
    }
    }

    public class ServiceB : IService
    {
    private readonly string _name;

    public ServiceB(string name)
    {
    _name = name;
    }

    public string DoWork()
    {
    throw new NotImplementedException();
    }
    }

    服务工厂
    public interface IServiceFactory
    {
    IService Create(string name);
    }

    public class ServiceAFactory : IServiceFactory
    {
    private readonly Func<string, ServiceA> _factory;

    public ServiceAFactory(Func<string, ServiceA> factory)
    {
    _factory = factory;
    }

    public IService Create(string name)
    {
    return _factory(name);
    }
    }

    public class ServiceBFactory : IServiceFactory
    {
    private readonly Func<string, ServiceB> _factory;

    public ServiceBFactory(Func<string, ServiceB> factory)
    {
    _factory = factory;
    }

    public IService Create(string name)
    {
    return _factory(name);
    }
    }

    服务注册
    builder.RegisterType<ServiceA>().As<ServiceA>();
    builder.RegisterType<ServiceB>().As<ServiceB>();
    builder.RegisterType<ServiceAFactory>().Keyed<IServiceFactory>(ServiceType.ServiceA);
    builder.RegisterType<ServiceBFactory>().Keyed<IServiceFactory>(ServiceType.ServiceB);
    builder.RegisterType<ComponentWithServiceDependency>().As<ComponentWithServiceDependency>();

    使用示例
    public class ComponentWithServiceDependency
    {
    private readonly IService _service;

    public ComponentWithServiceDependency(IIndex<ServiceType, IServiceFactory> serviceFactories)
    {
    // Resolve the ServiceB service implementation,
    // using the string "test" as its constructor dependency
    _service = serviceFactories[ServiceType.ServiceB].Create("test");
    }

    public string Test()
    {
    return _service.DoWork();
    }
    }

    关于autofac - 具有运行时构造函数参数的键控委托(delegate)工厂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25003048/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com