我的网络API 2应该为客户提供两个网址:test.mydomain.com和production.mydomain.com 当客户端访问测试时,我想为生产URL实例化测试数据库上下文和生产数据库。
目前我可以手动实例化:在控制器内的每个动作上,我可以检查网址并确定是否加载,如果加载那个。 但是我想自动设置数据库,而不检查每个操作的请求URL。我尝试在控制器构造函数中读取请求上下文,但在那个阶段它不存在。
动作过滤器? OnActionExecuting?但是我如何在过滤器中实例化它并在控制器动作中使用它?还有其他建议吗?
答案 0 :(得分:0)
正如Erik所指出的,使用依赖注入可以很容易地解决这个问题。
以下是使用AutoFac的示例:
public interface IContextCache
{
DbContext CurrentContext { get; set; }
}
// This will be wired as instance per api request
// and hence return the same context across the entire
// request from handler to controller
public class ContextCache : IContextCache
{
public DbContext CurrentContext { get; set; }
}
public interface IContextFactory
{
DbContext Create(Uri requestUri);
}
public class ContextFactory : IContextFactory
{
public DbContext Create(Uri requestUri)
{
return CreateContextBasedOnUri(requestUri);
}
}
// This is fired before the controller and creates and caches
// as per url context
public class ContextHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
var dependencyScope = request.GetDependencyScope();
var contextFactory = (IContextFactory)dependencyScope.GetService(typeof(IContextFactory));
var contextCache = (IContextFache)dependencyScope.GetService(typeof(IContextCache));
var context = contextFactory.Create(request.RequestUri);
contextCache.CurrentContext = context;
return base.SendAsync(request, cancellationToken);
}
}
// Uses the per api request scoped cache to retrieve the
// correct context
public class MyController : ApiController
{
public MyController(IContextCache contextCache)
{
var context = contextCache.CurrentContext;
}
}
// AutoFac wiring
// Perform boiler plate AutoFac registration for WebApi
// (See AutoFac documentation)
// Custom registrations
builder.RegisterType<ContextCache>()
.As<IContextCache>()
.InstancePerApiRequest();
builder.RegisterType<ContextFactoy>()
.As<IContextFactory>()
.InstancePerDependency();
// Handler registration
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new ContextHandler());
}