我关注了这篇文章,除了依赖注入(部分)之外,一切都正常了。在我的项目中,我正在使用统一,我正在尝试创建一个自定义事务属性,其目的是在执行操作之前启动 NHibernate 事务并在方法执行之后提交/回滚事务。
这是我的属性的定义:-
public class TransactionAttribute : Attribute
{
}
以下是我的 TransactionFilter 的定义
public class TransactionFilter : IActionFilter
{
private readonly IUnitOfWork _unitOfWork;
public TransactionFilter(IUnitOfWork uow) {
_unitOfWork = uow;
}
public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) {
var transAttribute = actionContext.ActionDescriptor.GetCustomAttributes<TransactionAttribute>().SingleOrDefault();
if (transAttribute == null) {
return continuation();
}
var transaction = uow.BeginTransaction();
return continuation().ContinueWith(t =>
{
try{
transaction.Commit();
return t.Result;
}
catch(Exception e)
{
transaction.Rollback();
return new ExceptionResult(ex, actionContext.ControllerContext.Controller as ApiController).ExecuteAsync(cancellationToken).Result;
}
}
}
}
我创建了一个自定义过滤器提供程序,它使用统一来构建这个过滤器。
public class UnityActionFilterProvider
: ActionDescriptorFilterProvider,
IFilterProvider
{
private readonly IUnityContainer container;
public UnityActionFilterProvider(IUnityContainer container)
{
this.container = container;
}
public new IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
{
foreach (IActionFilter actionFilter in container.ResolveAll<IActionFilter>())
{
// TODO: Determine correct FilterScope
yield return new FilterInfo(actionFilter, FilterScope.Global);
}
}
}
我在UnityWebApiActivator中注册了UnityActionFilterProvider(我使用的是Unity.AspNet.WebApi包)如下
public static void Start()
{
var container = UnityConfig.GetConfiguredContainer();
var resolver = new UnityDependencyResolver(container);
var config = GlobalConfiguration.Configuration;
config.DependencyResolver = resolver;
var providers = config.Services.GetFilterProviders();
var defaultProvider = providers.Single(i => i is ActionDescriptorFilterProvider);
config.Services.Remove(typeof(IFilterProvider), defaultProvider);
config.Services.Add(typeof(IFilterProvider), new UnityActionFilterProvider(container));
}
问题是对于任何操作的第一个请求一切正常,但对同一操作的后续请求不会重新创建 TransactionFilter,这意味着它不会调用构造函数来分配新的 UOW。我不认为我可以禁用动作过滤器缓存。
我现在唯一的选择是使用服务定位器模式并使用 ExecuteActionFilterAsync 中的容器获取 UOW 实例,我认为这会扼杀这个目的,我最好实现自定义 ActionFilterAttribute。
有什么建议么 ?