.net core 使用Castle DynamicProxy的.NET核心默认依赖项注入

.net core 使用Castle DynamicProxy的.NET核心默认依赖项注入,.net-core,dependency-injection,autofac,aop,castle-dynamicproxy,.net Core,Dependency Injection,Autofac,Aop,Castle Dynamicproxy,我有许多AOP库,它们使用Castle DynamicProxy和Autofac DI容器进行日志记录、审核、事务控制等 我想知道是否有一种方法可以使用默认的.NETCoreDI容器声明拦截器。拥有这种灵活性会很好,因为许多.NET核心项目不使用Autofac。基本.NET核心容器没有任何额外的特性,如拦截器。NET Core中的DI容器可以替换为Autofac之类的容器的全部原因是,一旦超出默认容器,您就可以移动到另一个容器。基本.NET Core容器没有任何诸如拦截器之类的额外功能。NET

我有许多AOP库,它们使用Castle DynamicProxy和Autofac DI容器进行日志记录、审核、事务控制等


我想知道是否有一种方法可以使用默认的.NETCoreDI容器声明拦截器。拥有这种灵活性会很好,因为许多.NET核心项目不使用Autofac。

基本.NET核心容器没有任何额外的特性,如拦截器。NET Core中的DI容器可以替换为Autofac之类的容器的全部原因是,一旦超出默认容器,您就可以移动到另一个容器。

基本.NET Core容器没有任何诸如拦截器之类的额外功能。NET Core中的DI容器可以替换为Autofac之类的容器的全部原因是,一旦超出默认容器,您可以移动到另一个容器。

是的,您可以使用Core DI使用DynamicProxy。我在上写了一篇博文解释它,但下面是代码:

创建一个属性

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class CacheAttribute : Attribute
{
    public int Seconds { get; set; } = 30;
}
创建拦截器(需要Castle.Core nuget包)

添加扩展方法以帮助在DI中注册类:

public static void AddProxiedScoped<TInterface, TImplementation>
    (this IServiceCollection services)
    where TInterface : class
    where TImplementation : class, TInterface
{
    // This registers the underlying class
    services.AddScoped<TImplementation>();
    services.AddScoped(typeof(TInterface), serviceProvider =>
    {
        // Get an instance of the Castle Proxy Generator
        var proxyGenerator = serviceProvider
            .GetRequiredService<ProxyGenerator>();
        // Have DI build out an instance of the class that has methods
        // you want to cache (this is a normal instance of that class 
        // without caching added)
        var actual = serviceProvider
            .GetRequiredService<TImplementation>();
        // Find all of the interceptors that have been registered, 
        // including our caching interceptor.  (you might later add a 
        // logging interceptor, etc.)
        var interceptors = serviceProvider
            .GetServices<IInterceptor>().ToArray();
        // Have Castle Proxy build out a proxy object that implements 
        // your interface, but adds a caching layer on top of the
        // actual implementation of the class.  This proxy object is
        // what will then get injected into the class that has a 
        // dependency on TInterface
        return proxyGenerator.CreateInterfaceProxyWithTarget(
            typeof(TInterface), actual, interceptors);
    });
}
公共静态void addProxiedScope
(此IServiceCollection服务)
TInterface的位置:类
其中TImplementation:类,TInterface
{
//这将注册基础类
services.addScope();
services.addScope(typeof(TInterface),serviceProvider=>
{
//获取Castle代理生成器的实例
var proxyGenerator=serviceProvider
.GetRequiredService();
//让DI构建具有方法的类的实例
//您想要缓存(这是该类的普通实例)
//(未添加缓存)
var实际=服务提供者
.GetRequiredService();
//查找所有已注册的拦截器,
//包括我们的缓存拦截器
//日志拦截器等)
var拦截器=服务提供者
.GetServices().ToArray();
//让Castle Proxy构建一个实现
//您的接口,但在
//类的实际实现。此代理对象为
//然后将什么注入到具有
//对TInterface的依赖
返回proxyGenerator.CreateInterfaceProxyWithTarget(
类型(TInterface)、实际、拦截器;
});
}
将这些行添加到Startup.cs中的ConfigureServices

// Setup Interception
services.AddSingleton(new ProxyGenerator());
services.AddScoped<IInterceptor, CacheInterceptor>(
//设置拦截
AddSingleton(新的ProxyGenerator());
services.AddScoped(
之后,如果要使用缓存拦截器,需要做两件事:

首先,将属性添加到方法中

[Cache(Seconds = 30)]
public async Task<IEnumerable<Person>> GetPeopleByLastName(string lastName)
{
    return SomeLongRunningProcess(lastName);
}
[缓存(秒=30)]
公共异步任务GetPeopleByLastName(字符串lastName)
{
返回SomeLongRunningProcess(lastName);
}
其次,使用代理/拦截在DI中注册类:

services.AddProxiedScoped<IPersonRepository, PersonRepository>();
services.AddScoped<IPersonRepository, PersonRepository>();
services.addProxiedScope();
而不是没有代理/拦截的正常方式:

services.AddProxiedScoped<IPersonRepository, PersonRepository>();
services.AddScoped<IPersonRepository, PersonRepository>();
services.addScope();

是的,您可以使用Core DI使用DynamicProxy。我在上写了一篇博客文章对此进行了解释,但下面是代码:

创建一个属性

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class CacheAttribute : Attribute
{
    public int Seconds { get; set; } = 30;
}
创建拦截器(需要Castle.Core nuget包)

添加扩展方法以帮助在DI中注册类:

public static void AddProxiedScoped<TInterface, TImplementation>
    (this IServiceCollection services)
    where TInterface : class
    where TImplementation : class, TInterface
{
    // This registers the underlying class
    services.AddScoped<TImplementation>();
    services.AddScoped(typeof(TInterface), serviceProvider =>
    {
        // Get an instance of the Castle Proxy Generator
        var proxyGenerator = serviceProvider
            .GetRequiredService<ProxyGenerator>();
        // Have DI build out an instance of the class that has methods
        // you want to cache (this is a normal instance of that class 
        // without caching added)
        var actual = serviceProvider
            .GetRequiredService<TImplementation>();
        // Find all of the interceptors that have been registered, 
        // including our caching interceptor.  (you might later add a 
        // logging interceptor, etc.)
        var interceptors = serviceProvider
            .GetServices<IInterceptor>().ToArray();
        // Have Castle Proxy build out a proxy object that implements 
        // your interface, but adds a caching layer on top of the
        // actual implementation of the class.  This proxy object is
        // what will then get injected into the class that has a 
        // dependency on TInterface
        return proxyGenerator.CreateInterfaceProxyWithTarget(
            typeof(TInterface), actual, interceptors);
    });
}
公共静态void addProxiedScope
(此IServiceCollection服务)
TInterface的位置:类
其中TImplementation:类,TInterface
{
//这将注册基础类
services.addScope();
services.addScope(typeof(TInterface),serviceProvider=>
{
//获取Castle代理生成器的实例
var proxyGenerator=serviceProvider
.GetRequiredService();
//让DI构建具有方法的类的实例
//您想要缓存(这是该类的普通实例)
//(未添加缓存)
var实际=服务提供者
.GetRequiredService();
//查找所有已注册的拦截器,
//包括我们的缓存拦截器
//日志拦截器等)
var拦截器=服务提供者
.GetServices().ToArray();
//让Castle Proxy构建一个实现
//您的接口,但在
//类的实际实现。此代理对象为
//然后将什么注入到具有
//对TInterface的依赖
返回proxyGenerator.CreateInterfaceProxyWithTarget(
类型(TInterface)、实际、拦截器;
});
}
将这些行添加到Startup.cs中的ConfigureServices

// Setup Interception
services.AddSingleton(new ProxyGenerator());
services.AddScoped<IInterceptor, CacheInterceptor>(
//设置拦截
AddSingleton(新的ProxyGenerator());
services.AddScoped(
之后,如果要使用缓存拦截器,需要做两件事:

首先,将属性添加到方法中

[Cache(Seconds = 30)]
public async Task<IEnumerable<Person>> GetPeopleByLastName(string lastName)
{
    return SomeLongRunningProcess(lastName);
}
[缓存(秒=30)]
公共异步任务GetPeopleByLastName(字符串lastName)
{
返回SomeLongRunningProcess(lastName);
}
其次,使用代理/拦截在DI中注册类:

services.AddProxiedScoped<IPersonRepository, PersonRepository>();
services.AddScoped<IPersonRepository, PersonRepository>();
services.addProxiedScope();
而不是没有代理/拦截的正常方式:

services.AddProxiedScoped<IPersonRepository, PersonRepository>();
services.AddScoped<IPersonRepository, PersonRepository>();
services.addScope();