假设我有这样的界面:
interface IDateTimeProvider
{
DateTime GetNow();
}
和两个实现:
public class DateTimeProvider : IDateTimeProvider
{
public DateTime GetNow()
{
return DateTime.Now;
}
}
public class DateTimeUtcProvider : IDateTimeProvider
{
public DateTime GetNow()
{
return DateTime.UtcNow;
}
}
我使用Autofac将依赖项注入到我的服务中。我的某些服务需要两种实现,而只有一种:
public class ServiceBoth
{
(...)
public ServiceBoth(IDateTimeProvider provider, IDateTimeProvider utcProvider)
{
(...)
}
}
public class Service
{
(...)
public ServiceBoth(IDateTimeProvider provider)
{
(...)
}
}
public class ServiceUtc
{
(...)
public ServiceBoth(IDateTimeProvider utcProvider)
{
(...)
}
}
如您所见,当我想注入“ DateTimeProvider”时,我将名称为“ provider”的参数称为参数,而当我想注入“ DateTimeUtcProvider”时,则将其名称为“ utcProvider”的参数指针。
现在,我想使用Autofac来实现这种依赖注入方案: 1.我有两种接口实现。 2.注入哪个实现取决于构造函数的参数名称。 3.一切都应该在全局范围内实现,我不想为每个使用IDateTimeProvider的服务创建解析机制。
如何?
编辑:正如史蒂文(Steven)在下面的评论中指出的那样,这种方法违反了《里斯科夫替代原理》,因此我决定放弃这种解决方案。但是,如果有人对如何实施此“不良解决方案”有任何想法,请随时分享。
答案 0 :(得分:0)
我认为,Autofac无法识别参数名称,但是您可以定义第二个接口,该接口继承自IDateTimeProvider并且还包含GetNow()
public interface IDateTimeProvider
{
DateTime GetNow();
}
public interface IDateTimeUtcProvider : IDateTimeProvider
{
}
Autofac现在可以解析正确的服务:
var builder = new ContainerBuilder();
builder.RegisterType<DateTimeProvider>().As<IDateTimeProvider>();
builder.RegisterType<DateTimeUtcProvider>().As<IDateTimeUtcProvider>();
builder.RegisterType<ServiceBoth>();
builder.RegisterType<Service>();
builder.RegisterType<UtcService>();
var container = builder.Build();
using (var scope = container.BeginLifetimeScope())
{
var sb = scope.Resolve<ServiceBoth>();
var s = scope.Resolve<Service>();
var su = scope.Resolve<UtcService>();
Console.WriteLine($"Both: {sb.Dt}, {sb.UtcDt}; Norm: {s.Dt}; Utc: {su.Dt}");
Console.ReadLine();
}