Внедрение многопользовательских репозиториев с помощью StructureMap в ASP.NET MVC - PullRequest
6 голосов
/ 01 мая 2010

Я реализую StructureMap в многопользовательском приложении ASP.NET MVC, чтобы внедрить экземпляры моих репозиториев , которые получают данные на основе интерфейса ITenantContext. Tenant, о котором идет речь, определяется из RouteData в базовом контроллере OnActionExecuting.

Как мне сказать StructureMap создать TenantContext(tenantID);, где tenantID получен из моего RouteData или какого-либо базового свойства контроллера?

Базовый контроллер

С учетом следующего маршрута:

{tenant}/{controller}/{action}/{id}

Мой базовый контроллер получает и сохраняет правильный Tenant на основе параметра URL-адреса {tenant}. Используя Tenant, можно создать хранилище с ITenantContext для извлечения только данных, относящихся к этому арендатору.

Исходя из других вопросов DI, может ли AbstractFactory быть решением?

Ответы [ 2 ]

7 голосов
/ 03 мая 2010

Не храните клиента на контроллере, так как он не будет доступен для внедренных служб, как вы обнаружили. Создайте тонкий сервис, единственной обязанностью которого является определение идентификатора клиента. Служба может получить доступ к статике и HttpContext напрямую. Этот класс не обязательно должен быть модульно-тестируемым - его цель - изолировать остальную часть системы, чтобы другие классы были тестируемыми.

Если вы хотите, чтобы ITenantContext был этим сервисом, он может выглядеть примерно так:

public class TenantContext : ITenantContext
{
    public string GetTenant()
    {
        var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current));
        return routeData.GetRequiredString("tenant");
    }
}

Теперь ваш контроллер может зависеть от интерфейса вашего репозитория, а реализация вашего репозитория (любой другой обслуживающий сервис) может зависеть от ITenantContext. Контролеру не нужно знать об арендаторах.

1 голос
/ 01 мая 2010

@ FreshCode, я не знаю, есть ли у вас зависимость от хранилища непосредственно в вашем контроллере или у вашего контроллера есть зависимость от службы, которая, в свою очередь, зависит от хранилища. Однако, когда контроллер создается посредством Structuremap, служба или хранилище должны быть уже созданы. Мы определяем клиента в Begin_Request и внедряем созданный экземпляр контекста в структурную карту с помощью метода Inject. Это выполняется раньше, чем фабрика контроллеров, поэтому, когда создается экземпляр контроллера, все его зависимости уже созданы.

Привет.

...