Я создаю .Net Web Api, который использует шаблон Service / Repository с Entity Framework.Ниже представлен контроллер с действиями CRUD, которые взаимодействуют со службой:
public class SomeController : BaseApiController
{
private IService _service;
public SomeController(IService _service)
{
_service = service;
}
public object Get() { return _service.GetItems(); }
...
}
Я хочу использовать Microsoft Unity IoC для вставки контекста базы данных в конструктор службы ниже:
// Service implements IService
public Service(SomeContext ctx) : base(ctx)
{
_alpha = new AlphaRepository(ctx);
_bravo = new BravoRepository(ctx);
}
Этохорошо работает для меня с одним, статическим DbContext.Однако Api должен использовать динамический DbContext, поскольку сервер и база данных не известны до тех пор, пока не будет выполнен запрос, и различные данные конфигурации не будут переданы через строку запроса, например? Client = Client & property = Property.Каждый клиент имеет свою собственную базу данных, и каждая база данных расположена на одном из двух серверов.
Существует внутренний пакет NuGet с незащищенной ContextFactory, который может быть вызван для получения соответствующего DbContext при выполнении запроса:
ContextFactory.GetSomeContext(client, prop);
Сначала я подумал об использовании ActionFilter на BaseController для анализа строки запроса HTTPActionContext Request для ключей Client и Property.С помощью этой информации контекст может быть получен и зарегистрирован с помощью контейнера Unity:
// Belongs to 'public class SomeFilterAttribute : ActionFilterAttribute'
public override void OnActionExecuting(HttpActionContext actionContext)
{
var someContext = ContextFactory.GetSomeContext(client, prop);
private IUnityContainer _unityContainer;
_unityContainer = (IUnityContainer)actionContext.Request.GetDependencyScope().GetService(typeof(IUnityContainer));
_unityContainer.RegisterInstance<SomeContext>(someContext, new PerThreadLifetimeManager());
...
}
Этот план не удался, когда я понял, что ActionFilter выполняется после инициализации SomeController, и поэтому его конструктор и конструктор Service ужезавершено выполнение, и уже слишком поздно зарегистрировать DbContext.
Вопрос: Каков наилучший способ извлечь динамический DbContext и использовать Unity для внедрения этого экземпляра в конструктор Service?
I 'мы читали об использовании делегатов, например
public delegate ISomeContext CreateSomeContext(string client, string prop);
, а затем в UnityConfig.cs RegisterComponents ()
container.RegisterInstance<CreateSomeContext>((c, p) => ContextFactory.GetSomeContext(c, p));
, но я не уверен, как на самом деле предоставить клиента и свойство во время выполненияиз строки запроса.
Спасибо за любую помощь!