PostSharp Кэширование MethodInterceptionAspect с использованием ASP.NET Core в оперативной памяти - PullRequest
0 голосов
/ 27 августа 2018
public class CacheAttribute : MethodInterceptionAspect
{
    public override void OnInvoke(MethodInterceptionArgs methodInterceptionArgs)
    {
        if ((methodInterceptionArgs.Method.Name == CacheAspectAction.Get.ToString()) 
            //&& (Memory.Cache[cacheKey] != null)
            )
        {
        //    methodInterceptionArgs.ReturnValue = HttpRuntime.Cache[cacheKey];
            return;
        }

        object returnVal = methodInterceptionArgs.Invoke(methodInterceptionArgs.Arguments);

        ClanCache(cacheKeyBase, cacheKey);

        if (returnVal != null)
            //Memory.Cache.Insert(cacheKey, returnVal, null, expirationInformation.AbsoluteExpiration, expirationInformation.SlidingExpiration);

        methodInterceptionArgs.ReturnValue = returnVal;
    }
}

Как получить доступ к кэшу в памяти в ASP.NET Core из любого класса, включая аспект PostSharp? Например, мне нужно получить доступ к IMemoryCache в MethodInterceptionAspect и OnMethodBoundaryAspect.

1 Ответ

0 голосов
/ 01 сентября 2018

Я собираюсь предположить, что вы используете встроенное внедрение зависимостей ASP.NET Core и реализацию IMemoryCache. Однако пример может быть легко адаптирован к другим реализациям. И я собираюсь выбрать подход Global Service Locator для разрешения зависимостей в аспекте. Ниже приведен модифицированный пример со страницы документации.

// A helper class that resolves services using built-in ASP.NET Core service provider.
public static class AspectServiceLocator
{
    private static IServiceProvider serviceProvider;

    public static void Initialize(IWebHost host)
    {
        serviceProvider = host.Services;
    }

    public static Lazy<T> GetService<T>() where T : class
    {
        return new Lazy<T>(GetServiceImpl<T>);
    }

    private static T GetServiceImpl<T>()
    {
        if (serviceProvider == null)
            throw new InvalidOperationException();

        return (T) serviceProvider.GetService(typeof(T));
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        IWebHost host = CreateWebHostBuilder(args).Build();

        // Initialize the AspectServiceLocator during ASP.NET Core program start-up
        AspectServiceLocator.Initialize(host);

        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

[PSerializable]
public class CacheAttribute : MethodInterceptionAspect
{
    private static Lazy<IMemoryCache> cache;

    static CacheAttribute()
    {
        // Use AspectServiceLocator to initialize the cache service field at application run-time.
        if (!PostSharpEnvironment.IsPostSharpRunning)
        {
            cache = AspectServiceLocator.GetService<IMemoryCache>();
        }
    }

    public override void OnInvoke(MethodInterceptionArgs args)
    {
        object cacheKey = args.Method.Name;
        object cachedResult;

        if (cache.Value.TryGetValue(cacheKey, out cachedResult))
        {
            args.ReturnValue = cachedResult;
            return;
        }

        args.Proceed();

        cache.Value.Set(cacheKey, args.ReturnValue);
    }
}
...