I have a BasePage class with two properties of the same dependency type and I couldn't find a way to provide the required parameters using Autofac
I tried to register the types and both BasePage properties are pointing now to the same last registered component which is FaxSender, I added a breakpoint at the function TryGetDeclaringProperty and it works fine and checking the names of properties of the BasePage class.
[UPDATED Example]
public class BasePage : System.Web.UI.Page
{
public ISender EmailSender { get; set; }
public ISender FaxSender { get; set; }
}
public class EmailSender : ISender
{
private readonly SmtpClient _smtpClient;
public EmailSender(SmtpClient smtpClient)
{
_smtpClient = smtpClient;
}
public void Send(INotification notification)
{
//...
}
}
public class FaxSender : ISender
{
private readonly SmtpClient _smtpClient;
public FaxSender(SmtpClient smtpClient)
{
_smtpClient = smtpClient;
}
public void Send(INotification notification)
{
//...
}
}
in Global.asax.cs
var emailSmtp = new SmtpClient
{
...
};
var emailSender = new EmailSender(emailSmtp);
var faxSmtp = new SmtpClient
{
...
};
var faxSender = new FaxSender(faxSmtp);
var builder = new ContainerBuilder();
//--------------------------------
builder.RegisterType<BasePage>()
.WithProperties(new Parameter[]{
new NamedPropertyParameter("EmailSender", emailSender),
new NamedPropertyParameter("FaxSender", faxSender),
});
//--------------------------------
//OR
//--------------------------------
builder.RegisterType<EmailSender>()
.Named<ISender>("email")
.WithParameter("smtpClient", emailSmtp);
builder.RegisterType<FaxSender>()
.Named<ISender>("fax")
.WithParameter("smtpClient", faxSmtp);
builder.RegisterType<BasePage>()
.AsSelf()
.WithProperties(new Parameter[] {
new ResolvedParameter(
(pi, c) => {
PropertyInfo ppi = null;
if (pi.TryGetDeclaringProperty(out ppi)) {
return ppi.Name == "EmailSender";
} else {
return false;
}
},
(pi, c) => c.ResolveNamed<ISender>("email")),
new ResolvedParameter(
(pi, c) => {
PropertyInfo ppi = null;
if (pi.TryGetDeclaringProperty(out ppi)) {
return ppi.Name == "FaxSender";
} else {
return false;
}
},
(pi, c) => c.ResolveNamed<ISender>("fax"))
});
//--------------------------------
//and then
var container = builder.Build();
_containerProvider = new ContainerProvider(container);
using (var scope = container.BeginLifetimeScope())
{
scope.Resolve<BasePage>();
}
in Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
//Object reference not set to an instance of an object. [Exception in both cases]
EmailSender.Send(new EmailNotification(...);
FaxSender.Send(new FaxNotification(...));
}