IExchangeDataProvider 接口有多种实现。
服务:
public interface IExchangeDataProvider
{
string ProviderName { get; set; }
}
public class DataProvider_1 : IExchangeDataProvider
{
public string ProviderName { get; set; } = "DataProvider_1";
}
public class DataProvider_2 : IExchangeDataProvider
{
public string ProviderName { get; set; } = "DataProvider_2";
}
在 Autofac 容器中注册:
builder.RegisterType<DataProvider_1>().As<IExchangeDataProvider>().InstancePerDependency();
builder.RegisterType<DataProvider_2>().As<IExchangeDataProvider>().InstancePerDependency();
我不仅需要IEnumerable<IExchangeDataProvider>注入到构造函数中,还IEnumerable<Func<IExchangeDataProvider>>
需要能够选择所需的服务工厂。
依赖解析
public class MainService
{
IEnumerable<Func<IExchangeDataProvider>> _providerFactories;
public MainService(IEnumerable<Func<IExchangeDataProvider>> providerFactories)
{
_providerFactories= providerFactories;
}
public void Foo()
{
for(int i=0; i<10; i++)
{
var providerName= GetProviderName(i); // providerName= "DataProvider_1"
var dataProviderFactory= _providerFactories.FirstOrDefault("найти фабрику по имени или еще как то для создания именно DataProvider_1 без создания DataProvider_2");
var dataProvider= dataProviderFactory();
}
}
}
我尝试通过反射工厂实际创建的类名,但它也没有成功,我没有在那里找到它。
现在我没有理性地这样做(每次使用工厂时我都必须创建一个新的 IExchangeDataProvider 集合并在其中查找所需的元素)
public class MainService
{
Func<IEnumerable<IExchangeDataProvider>> _providerFactories;
public MainService(Func<IEnumerable<IExchangeDataProvider>> providerFactories)
{
_providerFactories= providerFactories;
}
public void Foo()
{
for(int i=0; i<10; i++)
{
var providerName= GetProviderName(i); // providerName= "DataProvider_1"
var dataProvider =_dataProviderCollectionFactory()?.FirstOrDefault(p=>p.ProviderName == dataProvider);
}
}
}
也许您想创建命名依赖项:
服务使用:
很容易猜到,一个简单的枚举
Func<...>原则上并不适合您:直到创建对象的那一刻,工厂才提供有关它将是哪种对象的任何信息。因此,您需要使用
Func<>. 例如,您可以从任何容器的这种通用方式开始:或者您可以使用元数据机制:
事实上,你可以在
Meta<Func<IExchangeDataProvider>>没有额外接口的情况下立即注入——但这会将你的代码绑定到你通常想要避免的 Autofac。或者,您可以使用属性来设置元数据:
最后,Autofac 有一个命名服务机制: