如何在 System.Web.UI.Page 中解析相同类型的多个依赖项,其中这些依赖项实现通用接口
how to resolve multiple dependencies of the same type in a System.Web.UI.Page where these dependencies implement a generic interface
在 BasePage.cs class 中,我有以下 IIndex 属性,它应该有两个 "or more" INotificationService 实现,可以使用密钥访问。
public class BasePage : Page
{
public IIndex<string, INotificationService<INotification>> NotificationServices { get; set; }
public INotificationService<INotification> EmailService
{
get
{
return NotificationServices["emailService"];
}
}
public INotificationService<INotification> FaxService
{
get
{
return NotificationServices["faxService"];
}
}
}
具体类:
public class FaxNotificationService : INotificationService<FaxNotification>
{
private IClient _smtpClient;
public FaxNotificationService(IClient smtpClient)
{
_smtpClient = smtpClient;
}
public void Send(FaxNotification notification)
{
_smtpClient.Send(notification);
}
}
public class EmailNotificationService : INotificationService<EmailNotification>
{
private IClient _smtpClient;
public EmailNotificationService(IClient smtpClient)
{
_smtpClient = smtpClient;
}
public void Send(EmailNotification notification)
{
_smtpClient.Send(notification);
}
}
在Global.asax.cs
void Application_Start(object sender, EventArgs e)
{
var emailSmtp = new SmtpWrapper(new SmtpClient
{
...
});
var faxSmtp = new SmtpWrapper(new SmtpClient
{
...
});
var builder = new ContainerBuilder();
// before having the generic interface the following commented code worked perfectly fine
//builder.RegisterType<EmailNotificationService>()
// .Named<INotificationService>("emailService")
// .WithParameter("smtpClient", emailSmtp);
//builder.RegisterType<FaxNotificationService>()
// .Named<INotificationService>("faxService")
// .WithParameter("smtpClient", faxSmtp);
builder.RegisterType<EmailNotificationService>()
.Named<INotificationService<INotification>>("emailService")
.WithParameter("smtpClient", emailSmtp);
builder.RegisterType<BasePage>().AsSelf();
var build = builder.Build();
_containerProvider = new ContainerProvider(build);
using (var scope = build.BeginLifetimeScope())
{
var service = scope.Resolve<BasePage>();
}
}
在 Global.asax.cs 中,我尝试以某种方式注册 EmailNotificationService,但出现异常:
类型 'NotificationServices.EmailNotificationService' 无法分配给服务 'emailService (Shared.NotificationServices.Abstractions.INotificationService`1[[Shared.NotificationServices.Abstractions.INotification ...]
现在我知道为什么它不起作用了。
因为在 C# 中甚至不可能执行以下操作:
INotificationService<INotification> service = new EmailNotificationService(new SmtpWrapper(new SmtpClient()));
后一行代码将导致编译时错误:
无法将类型 'NotificationServices.EmailNotificationService' 隐式转换为 'Shared.NotificationServices.Abstractions.INotificationService'。存在显式转换(是否缺少转换?)
大家有什么想法:)
它们可能实现了相同的接口,但不一定被同等对待。类型是一个重要的区别因素。 Solving this is an FAQ in the docs.
在 BasePage.cs class 中,我有以下 IIndex 属性,它应该有两个 "or more" INotificationService 实现,可以使用密钥访问。
public class BasePage : Page
{
public IIndex<string, INotificationService<INotification>> NotificationServices { get; set; }
public INotificationService<INotification> EmailService
{
get
{
return NotificationServices["emailService"];
}
}
public INotificationService<INotification> FaxService
{
get
{
return NotificationServices["faxService"];
}
}
}
具体类:
public class FaxNotificationService : INotificationService<FaxNotification>
{
private IClient _smtpClient;
public FaxNotificationService(IClient smtpClient)
{
_smtpClient = smtpClient;
}
public void Send(FaxNotification notification)
{
_smtpClient.Send(notification);
}
}
public class EmailNotificationService : INotificationService<EmailNotification>
{
private IClient _smtpClient;
public EmailNotificationService(IClient smtpClient)
{
_smtpClient = smtpClient;
}
public void Send(EmailNotification notification)
{
_smtpClient.Send(notification);
}
}
在Global.asax.cs
void Application_Start(object sender, EventArgs e)
{
var emailSmtp = new SmtpWrapper(new SmtpClient
{
...
});
var faxSmtp = new SmtpWrapper(new SmtpClient
{
...
});
var builder = new ContainerBuilder();
// before having the generic interface the following commented code worked perfectly fine
//builder.RegisterType<EmailNotificationService>()
// .Named<INotificationService>("emailService")
// .WithParameter("smtpClient", emailSmtp);
//builder.RegisterType<FaxNotificationService>()
// .Named<INotificationService>("faxService")
// .WithParameter("smtpClient", faxSmtp);
builder.RegisterType<EmailNotificationService>()
.Named<INotificationService<INotification>>("emailService")
.WithParameter("smtpClient", emailSmtp);
builder.RegisterType<BasePage>().AsSelf();
var build = builder.Build();
_containerProvider = new ContainerProvider(build);
using (var scope = build.BeginLifetimeScope())
{
var service = scope.Resolve<BasePage>();
}
}
在 Global.asax.cs 中,我尝试以某种方式注册 EmailNotificationService,但出现异常:
类型 'NotificationServices.EmailNotificationService' 无法分配给服务 'emailService (Shared.NotificationServices.Abstractions.INotificationService`1[[Shared.NotificationServices.Abstractions.INotification ...]
现在我知道为什么它不起作用了。 因为在 C# 中甚至不可能执行以下操作:
INotificationService<INotification> service = new EmailNotificationService(new SmtpWrapper(new SmtpClient()));
后一行代码将导致编译时错误:
无法将类型 'NotificationServices.EmailNotificationService' 隐式转换为 'Shared.NotificationServices.Abstractions.INotificationService'。存在显式转换(是否缺少转换?)
大家有什么想法:)
它们可能实现了相同的接口,但不一定被同等对待。类型是一个重要的区别因素。 Solving this is an FAQ in the docs.