Browse Source

Set options in UOW interceptor and action filter.

pull/112/head
Halil İbrahim Kalkan 9 years ago
parent
commit
51f450b207
  1. 29
      src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs
  2. 16
      src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkDefaultOptions.cs
  3. 15
      src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkHelper.cs
  4. 33
      src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs
  5. 6
      test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/AbpIdentityApplicationTestModule.cs

29
src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs

@ -1,5 +1,8 @@
using System.Threading.Tasks; using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow; using Volo.Abp.Uow;
@ -10,10 +13,12 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
public const string UnitOfWorkReservationName = "_AbpActionUnitOfWork"; public const string UnitOfWorkReservationName = "_AbpActionUnitOfWork";
private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly UnitOfWorkDefaultOptions _defaultOptions;
public AbpUowActionFilter(IUnitOfWorkManager unitOfWorkManager) public AbpUowActionFilter(IUnitOfWorkManager unitOfWorkManager, IOptions<UnitOfWorkDefaultOptions> options)
{ {
_unitOfWorkManager = unitOfWorkManager; _unitOfWorkManager = unitOfWorkManager;
_defaultOptions = options.Value;
} }
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
@ -24,7 +29,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
return; return;
} }
var unitOfWorkAttr = UnitOfWorkHelper.GetUnitOfWorkAttributeOrNull(context.ActionDescriptor.GetMethodInfo()); var methodInfo = context.ActionDescriptor.GetMethodInfo();
var unitOfWorkAttr = UnitOfWorkHelper.GetUnitOfWorkAttributeOrNull(methodInfo);
if (unitOfWorkAttr?.IsDisabled == true) if (unitOfWorkAttr?.IsDisabled == true)
{ {
@ -32,9 +38,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
return; return;
} }
var options = new UnitOfWorkOptions(); var options = CreateOptions(context, unitOfWorkAttr);
unitOfWorkAttr?.SetOptions(options);
if (_unitOfWorkManager.TryBeginReserved(UnitOfWorkReservationName, options)) if (_unitOfWorkManager.TryBeginReserved(UnitOfWorkReservationName, options))
{ {
@ -51,5 +55,18 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
} }
} }
} }
private UnitOfWorkOptions CreateOptions(ActionExecutingContext context, UnitOfWorkAttribute unitOfWorkAttr)
{
var options = new UnitOfWorkOptions();
unitOfWorkAttr?.SetOptions(options);
options.IsTransactional = _defaultOptions.CalculateIsTransactional(
autoValue: !string.Equals(context.HttpContext.Request.Method, HttpMethod.Get.Method, StringComparison.OrdinalIgnoreCase)
);
return options;
}
} }
} }

16
src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkDefaultOptions.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Data; using System.Data;
using System.Reflection;
namespace Volo.Abp.Uow namespace Volo.Abp.Uow
{ {
@ -30,5 +31,20 @@ namespace Volo.Abp.Uow
return options; return options;
} }
internal bool CalculateIsTransactional(bool autoValue)
{
switch (TransactionBehavior)
{
case UnitOfWorkTransactionBehavior.Enabled:
return true;
case UnitOfWorkTransactionBehavior.Disabled:
return false;
case UnitOfWorkTransactionBehavior.Auto:
return autoValue;
default:
throw new AbpException("Not implemented TransactionBehavior value: " + TransactionBehavior);
}
}
} }
} }

15
src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkHelper.cs

@ -1,5 +1,6 @@
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using JetBrains.Annotations;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
@ -25,13 +26,16 @@ namespace Volo.Abp.Uow
return false; return false;
} }
public static bool IsUnitOfWorkMethod(MethodInfo methodInfo) public static bool IsUnitOfWorkMethod([NotNull] MethodInfo methodInfo, [CanBeNull] out UnitOfWorkAttribute unitOfWorkAttribute)
{ {
Check.NotNull(methodInfo, nameof(methodInfo));
//Method declaration //Method declaration
var attrs = methodInfo.GetCustomAttributes(true).OfType<UnitOfWorkAttribute>().ToArray(); var attrs = methodInfo.GetCustomAttributes(true).OfType<UnitOfWorkAttribute>().ToArray();
if (attrs.Any()) if (attrs.Any())
{ {
return true; unitOfWorkAttribute = attrs.First();
return !unitOfWorkAttribute.IsDisabled;
} }
if (methodInfo.DeclaringType != null) if (methodInfo.DeclaringType != null)
@ -40,17 +44,20 @@ namespace Volo.Abp.Uow
attrs = methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(true).OfType<UnitOfWorkAttribute>().ToArray(); attrs = methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(true).OfType<UnitOfWorkAttribute>().ToArray();
if (attrs.Any()) if (attrs.Any())
{ {
return true; unitOfWorkAttribute = attrs.First();
return !unitOfWorkAttribute.IsDisabled;
} }
//Conventional classes //Conventional classes //TODO: Make this extendible to add new conventions!
if (typeof(IApplicationService).GetTypeInfo().IsAssignableFrom(methodInfo.DeclaringType) || if (typeof(IApplicationService).GetTypeInfo().IsAssignableFrom(methodInfo.DeclaringType) ||
typeof(IRepository).GetTypeInfo().IsAssignableFrom(methodInfo.DeclaringType)) typeof(IRepository).GetTypeInfo().IsAssignableFrom(methodInfo.DeclaringType))
{ {
unitOfWorkAttribute = null;
return true; return true;
} }
} }
unitOfWorkAttribute = null;
return false; return false;
} }

33
src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs

@ -1,4 +1,8 @@
using System.Threading.Tasks; using System;
using System.Net.Http;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy; using Volo.Abp.DynamicProxy;
@ -7,40 +11,55 @@ namespace Volo.Abp.Uow
public class UnitOfWorkInterceptor : AbpInterceptor, ITransientDependency public class UnitOfWorkInterceptor : AbpInterceptor, ITransientDependency
{ {
private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly UnitOfWorkDefaultOptions _defaultOptions;
public UnitOfWorkInterceptor(IUnitOfWorkManager unitOfWorkManager) public UnitOfWorkInterceptor(IUnitOfWorkManager unitOfWorkManager, IOptions<UnitOfWorkDefaultOptions> options)
{ {
_unitOfWorkManager = unitOfWorkManager; _unitOfWorkManager = unitOfWorkManager;
_defaultOptions = options.Value;
} }
public override void Intercept(IAbpMethodInvocation invocation) public override void Intercept(IAbpMethodInvocation invocation)
{ {
if (!UnitOfWorkHelper.IsUnitOfWorkMethod(invocation.Method)) if (!UnitOfWorkHelper.IsUnitOfWorkMethod(invocation.Method, out var unitOfWorkAttribute))
{ {
invocation.Proceed(); invocation.Proceed();
return; return;
} }
using (var uow = _unitOfWorkManager.Begin()) using (var uow = _unitOfWorkManager.Begin(CreateOptions(invocation, unitOfWorkAttribute)))
{ {
invocation.Proceed(); invocation.Proceed();
uow.Complete(); uow.Complete();
} }
} }
public override async Task InterceptAsync(IAbpMethodInvocation invocation) public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{ {
if (!UnitOfWorkHelper.IsUnitOfWorkMethod(invocation.Method)) if (!UnitOfWorkHelper.IsUnitOfWorkMethod(invocation.Method, out var unitOfWorkAttribute))
{ {
await invocation.ProceedAsync(); await invocation.ProceedAsync();
return; return;
} }
using (var uow = _unitOfWorkManager.Begin()) using (var uow = _unitOfWorkManager.Begin(CreateOptions(invocation, unitOfWorkAttribute)))
{ {
await invocation.ProceedAsync(); await invocation.ProceedAsync();
await uow.CompleteAsync(); await uow.CompleteAsync();
} }
} }
private UnitOfWorkOptions CreateOptions(IAbpMethodInvocation invocation, [CanBeNull] UnitOfWorkAttribute unitOfWorkAttribute)
{
var options = new UnitOfWorkOptions();
unitOfWorkAttribute?.SetOptions(options);
options.IsTransactional = _defaultOptions.CalculateIsTransactional(
autoValue: !invocation.Method.Name.StartsWith("Get", StringComparison.InvariantCultureIgnoreCase)
);
return options;
}
} }
} }

6
test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/AbpIdentityApplicationTestModule.cs

@ -5,6 +5,7 @@ using Volo.Abp.Autofac;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Identity.EntityFrameworkCore; using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Uow;
namespace Volo.Abp.Identity namespace Volo.Abp.Identity
{ {
@ -26,6 +27,11 @@ namespace Volo.Abp.Identity
context.DbContextOptions.UseInMemoryDatabase(databaseName); context.DbContextOptions.UseInMemoryDatabase(databaseName);
}); });
}); });
services.Configure<UnitOfWorkDefaultOptions>(options =>
{
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; //EF in-memory database does not support transactions
});
} }
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)

Loading…
Cancel
Save