Как разрешить несколько зависимостей одного типа в System.Web.UI.Page, где эти зависимости реализуют универсальный интерфейс - PullRequest
0 голосов
/ 13 июня 2019

В классе BasePage.cs у меня есть следующее свойство IIndex, которое должно иметь две или более реализации 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». Явный разговорИон существует (вам не хватает актерского состава?)

Итак, есть идеи людей:)

1 Ответ

0 голосов
/ 14 июня 2019

Они могут реализовывать один и тот же интерфейс, но они не обязательно должны обрабатываться одинаково.Тип является важным отличием. Решение этой проблемы в документации.

...