Я следил за этим article и получил все, кроме зависимостей инъекции (частично). В моем проекте я использую единство, и я пытаюсь создать настраиваемый атрибут транзакции, целью которого является запуск транзакции NHibernate до выполнения действия и фиксация/откат транзакции после выполнения метода.Пользовательский фильтр действия единичная зависимость инъекция web api 2
Это определение моего атрибута: -
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);
}
}
}
я зарегистрировать UnityActionFilterProvider в UnityWebApiActivator (я использую пакет 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. Я не думаю, что могу отключить кэширование фильтра действий.
Единственный вариант, который я получил сейчас, это использовать шаблон локатора службы и получить экземпляр UOW с использованием контейнера внутри ExecuteActionFilterAsync, который, на мой взгляд, убивает цель этого, и мне лучше реализовать пользовательский ActionFilterAttribute.
Любые предложения?
Что такое 'repository'? Почему вводится «uow», если он не используется? –
К сожалению, это была опечатка. Репозиторий должен был быть uow. Я исправил исходный код. Спасибо – tangokhi