Пользовательские атрибуты и привязка MVC - PullRequest
0 голосов
/ 20 сентября 2011

У меня есть проект, в котором у нас есть собственная система регистрации клиентов и управления учетными записями, но некоторые элементы приложения связаны со сторонними службами.Эти сервисы имеют общую функциональность, например, создание учетной записи в своей собственной БД, но базовая реализация будет отличаться для того, как взаимодействовать со сторонними сервисами.

До сих пор я создавал CustomerRepository, который реализуетICustomerRepository.Это содержит все наши конкретные требования.ICustomerRepository также имеет определения общих методов, которые будут иметь все третьи стороны, но эти методы установлены на виртуальные в классе CustomerRepository, который выдает исключения, если они вызываются, требуя, чтобы вы реализовали их в сторонних классах.

Затем из этого я получаю:

ThirdPartyACustomer : CustomerRepository, IThirdPartyACustomer
ThirdPartyBCustomer : CustomerRepository

Как вы, вероятно, можете догадаться, оба этих подкласса наследуют и переопределяют виртуальные методы, за исключением ThirdPartyACustomer, который также реализует дополнительные методы, которые являются специфическимидля этого конкретного типа стороннего пользователя (например, может быть место, где пользователь может редактировать определенные функции, относящиеся к третьей стороне A, которую третья сторона B не предлагает.

Теперь, с этим изКстати, реальная основа моего вопроса:

Некоторые процессы (контроллеры) в моем приложении могут без проблем использовать CustomerRepository, поскольку им требуется только наша основная функциональность.

Другие процессы вприложение требует определенного типа ICustomerRepository для передачи.Все, что вызывает метод, который был определен как виртуальный в CustomerRepository, должно будет передать либо ThirdPartyACustomer, либо ThirdPartyBCustomer, чтобы была вызвана правильная реализация.

Первоначально при инициализации контроллера этого типа я делал бы что-то вроде:

public RegistrationController()
{
    ICustomerRepository _customerRepository = GetCustomerRepository();
}

, где GetCustomerRepository () имел некоторую логику, которая определяла, какой тип ThirdParty использовать, например, на основе субдомена.

Теперь я думаю, что я улучшаюэто путем создания пользовательского атрибута в соответствии с этим:

[ThirdPartyDependent]
class RegistrationController
{
    public RegistrationController(ICustomerRepository customerRepository)
    {
        _customerRepository = customerRepository;
    }
}

и перемещением совокупности параметра customerRepository в этот атрибут, например, там будет происходить логика в GetCustomerRepository.

Я вполне уверен, что что-то подобное выполнимо и, кажется, имеет смысл для целей тестирования, но не совсем уверен в том, что я должен искать в Google, или есть ли лучший способ сделать что-то, так что поискатьдля получения рекомендаций от кого-то более опытного с MVC.

1 Ответ

0 голосов
/ 20 сентября 2011

Это ответственность вашей структуры DI.Например, Ninject предоставляет вам доступ к HttpContext при настройке зависимостей, поэтому вы можете выбрать правильную реализацию на основе некоторого значения HttpContext.Например:

kernel.Bind<ICustomerRepository>().ToMethod(ctx =>
{
    if (HttpContext.Current.... Test something on the request or domain or whatever)
    {
        return new ThirdPartyACustomer();
    }
    return ThirdPartyBCustomer();
});

и тогда, конечно, ваш контроллер будет полностью агностиком.Все, на что должен обращать внимание контроллер - это то, что ему вводится какое-то хранилище, которое подчиняется данному контракту:

public class RegistrationController: Controller
{
    private readonly ICustomerRepository _customerRepository;
    public RegistrationController(ICustomerRepository customerRepository)
    {
        _customerRepository = customerRepository;
    }
}
...