Я реализую StructureMap в многопользовательском ASP.NET приложение MVC для введения экземпляров моих репозиториев арендатора, которые получают данные на основе ITenantContext
интерфейс. Tenant
рассматриваемый определяется от RouteData
в основном контроллере OnActionExecuting
.
Как я говорю StructureMap создавать TenantContext(tenantID);
где арендованный получен из моего RouteData
или некоторое основное свойство контроллера?
Учитывая следующий маршрут:
{tenant}/{controller}/{action}/{id}
Мой основной контроллер получает и хранит корректное Tenant
на основе {арендатор} параметр URL. Используя Tenant
, репозиторий с ITenantContext
может быть создан для получения только данных, которые относятся к тому арендатору.
На основе других вопросов о DI, мог AbstractFactory
быть решением?
Не сохраняйте арендатора на контроллере, так как он не будет доступен для внедренных служб, поскольку вы открыли. Создайте тонкую службу, единственная ответственность которой - определение идентификатора клиента. Служба может напрямую обращаться к статике и HttpContext. Этот класс не обязательно должен быть модульно-тестируемым - его цель - изолировать остальную часть системы, чтобы другие классы можно было тестировать.
Если вы хотите, чтобы этой службой был ITenantContext
, это могло бы выглядеть примерно так:
public class TenantContext : ITenantContext
{
public string GetTenant()
{
var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current));
return routeData.GetRequiredString("tenant");
}
}
Теперь ваш контроллер может просто зависеть от интерфейса вашего репозитория и реализации вашего репозитория (любых других служб, которые care) может зависеть от ITenantContext
. Контроллеру не нужно знать об арендаторах.
@FreshCode, я не знаю, есть ли у вас зависимость от репозитория непосредственно в вашем контроллере или ваш контроллер зависит от службы, которая в свою очередь, зависит от репозитория. Однако, когда контроллер создается структурной картой, служба или репозиторий должны быть уже созданы. Мы определяем клиента в Begin_Request и внедряем созданный контекст в карту структуры с помощью метода Inject. Это выполняется до того, как это сделает фабрика контроллеров, поэтому при создании экземпляра контроллера все его зависимости уже созданы.
С уважением.