Skip to content

Instantly share code, notes, and snippets.

@danielplawgo
Last active January 21, 2019 05:17
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save danielplawgo/a334feea119a1f5dfcae76904bfcecff to your computer and use it in GitHub Desktop.
Jak automatycznie ponawiać operacja oraz cachować dane z interceptorami w Autofac?
public class CacheInterceptor : IInterceptor
{
private ICacheService _cacheService;
public CacheInterceptor(ICacheService cacheService)
{
_cacheService = cacheService;
}
public void Intercept(IInvocation invocation)
{
var isLogic = invocation.TargetType.GetInterfaces()
.Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ILogic<>));
if (isLogic == false)
{
invocation.Proceed();
return;
}
var isGetById = invocation.Method.Name == nameof(ILogic<BaseModel>.GetById);
if (isGetById)
{
ProceedGetById(invocation);
return;
}
ProceedOtherMethods(invocation);
}
private void ProceedOtherMethods(IInvocation invocation)
{
var methodsToClear = new[] {nameof(ILogic<BaseModel>.Update), nameof(ILogic<BaseModel>.Delete)};
var clearCache = methodsToClear.Contains(invocation.Method.Name);
string key = "";
if (clearCache)
{
key = KeyFromObject(invocation);
}
invocation.Proceed();
if (clearCache)
{
_cacheService.Remove(key);
}
}
private void ProceedGetById(IInvocation invocation)
{
bool invoked = false;
var result = _cacheService.GetOrAdd(KeyFromParameter(invocation, invocation.Arguments[0] as int?), () =
{
invocation.Proceed();
invoked = true;
return invocation.ReturnValue;
});
if (invoked == false)
{
invocation.ReturnValue = result;
}
return;
}
private string KeyFromParameter(IInvocation invocation, int? id)
{
return $"{invocation.TargetType.FullName}-{id}";
}
private string KeyFromObject(IInvocation invocation)
{
var model = invocation.Arguments[0] as BaseModel;
if (model == null)
{
throw new ArgumentException("Wrong parameter type");
}
return $"{invocation.TargetType.FullName}-{model.Id}";
}
}
public class DataContextModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<DataContext>()
.InstancePerRequest();
builder.RegisterAssemblyTypes(typeof(Repository<>).Assembly)
.Where(t => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IRepository<>)))
.AsImplementedInterfaces()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(LoggerInterceptor))
.InterceptedBy(typeof(PollyInterceptor));
}
}
public class InterceptorsModule : Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.RegisterType<LoggerInterceptor>()
.SingleInstance();
}
}
2018-09-06 05:51:24.8486 INFO Before call: ProductLogic.GetAllActive
2018-09-06 05:51:24.8905 INFO Before call: ProductRepository.GetAllActive
2018-09-06 05:51:27.0856 INFO After call: ProductRepository.GetAllActive
2018-09-06 05:51:27.0856 INFO After call: ProductLogic.GetAllActive
Pierwsze wyświetlenie widoku edycji
2018-09-06 06:20:18.8329 INFO Before call: ProductLogic.GetById
2018-09-06 06:20:18.8329 TRACE Get [:AutofacInterceptors.Logics.ProductLogic-3] started.
2018-09-06 06:20:18.8470 TRACE Get [:AutofacInterceptors.Logics.ProductLogic-3], item NOT found in handle[0] 'handleName'.
2018-09-06 06:20:18.8470 INFO Before call: ProductRepository.GetById
2018-09-06 06:20:21.1078 INFO After call: ProductRepository.GetById
2018-09-06 06:20:21.1078 TRACE Add ['AutofacInterceptors.Logics.ProductLogic-3', exp:Default 00:00:00, lastAccess:06.09.2018 04:20:21] started.
2018-09-06 06:20:21.1218 TRACE Evict [:AutofacInterceptors.Logics.ProductLogic-3] from other handles excluding handle '0'.
2018-09-06 06:20:21.1218 INFO After call: ProductLogic.GetById
Drugie wyświetlenie widoku edycji
2018-09-06 06:20:26.5558 INFO Before call: ProductLogic.GetById
2018-09-06 06:20:26.5558 TRACE Get [:AutofacInterceptors.Logics.ProductLogic-3] started.
2018-09-06 06:20:26.5558 TRACE Get [:AutofacInterceptors.Logics.ProductLogic-3], found in handle[0] 'handleName'.
2018-09-06 06:20:26.5659 TRACE Start updating handles with ['AutofacInterceptors.Logics.ProductLogic-3', exp:Absolute 00:10:00, lastAccess:06.09.2018 04:20:26].
2018-09-06 06:20:26.5659 INFO After call: ProductLogic.GetById
Zapisanie produktu
2018-09-06 06:20:31.9539 INFO Before call: ProductLogic.GetById
2018-09-06 06:20:31.9618 TRACE Get [:AutofacInterceptors.Logics.ProductLogic-3] started.
2018-09-06 06:20:31.9618 TRACE Get [:AutofacInterceptors.Logics.ProductLogic-3], found in handle[0] 'handleName'.
2018-09-06 06:20:31.9618 TRACE Start updating handles with ['AutofacInterceptors.Logics.ProductLogic-3', exp:Absolute 00:10:00, lastAccess:06.09.2018 04:20:31].
2018-09-06 06:20:31.9618 INFO After call: ProductLogic.GetById
2018-09-06 06:20:31.9768 INFO Before call: ProductLogic.Update
2018-09-06 06:20:31.9768 INFO Before call: ProductRepository.Update
2018-09-06 06:20:32.0172 INFO After call: ProductRepository.Update
2018-09-06 06:20:32.0209 INFO Before call: ProductRepository.SaveChanges
2018-09-06 06:20:32.2310 INFO After call: ProductRepository.SaveChanges
2018-09-06 06:20:32.2310 TRACE Removing [:AutofacInterceptors.Logics.ProductLogic-3].
2018-09-06 06:20:32.2310 INFO After call: ProductLogic.Update
2018-09-05 06:13:11.3312 INFO Cache manager: adding cache handles...
2018-09-05 06:13:11.3601 INFO Creating handle handleName of type CacheManager.SystemRuntimeCaching.MemoryCacheHandle`1[TCacheValue].
2018-09-05 06:13:11.4586 INFO Before call: ProductLogic.GetAllActive
2018-09-05 06:13:11.4741 INFO Before call: ProductRepository.GetAllActive
2018-09-05 06:14:10.8945 ERROR Error - ProductRepository.GetAllActive - try retry (count: 1)
2018-09-05 06:14:27.8662 INFO After call: ProductRepository.GetAllActive
2018-09-05 06:14:27.8662 INFO After call: ProductLogic.GetAllActive
public class LoggerInterceptor : IInterceptor
{
private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
public void Intercept(IInvocation invocation)
{
_logger.Info($"Before call: {invocation.TargetType.Name}.{invocation.Method.Name}");
invocation.Proceed();
_logger.Info($"After call: {invocation.TargetType.Name}.{invocation.Method.Name}");
}
}
public class LogicModule : Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.RegisterAssemblyTypes(typeof(ILogic<>).Assembly)
.Where(t => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ILogic<>)))
.AsImplementedInterfaces()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(LoggerInterceptor));
}
}
public class PollyInterceptor : IInterceptor
{
private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
public void Intercept(IInvocation invocation)
{
Policy
.Handle<SqlException>()
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(10),
TimeSpan.FromSeconds(20),
TimeSpan.FromSeconds(50)
}, (ex, timeSpan, retryCount, context) =>
{
_logger.Error(ex, $"Error - {invocation.TargetType.Name}.{invocation.Method.Name} - try retry (count: {retryCount})");
})
.Execute(() => invocation.Proceed());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment