欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.NET Core依赖注入集成Dynamic Proxy

程序员文章站 2022-05-27 09:25:01
在《 "Castle DynamicProxy基本用法" 》中介绍了如何将DP与Autofac集成使用,而 .NET Core有自己的依赖注入容器,在不依赖第三方容器的基础上,如何实现动态代理就成了一个问题。 .NET Core依赖注入实现动态代理 我们知道,要创建一个代理对象,需要简单的三步: 创 ......

在《castle dynamicproxy基本用法》中介绍了如何将dp与autofac集成使用,而 .net core有自己的依赖注入容器,在不依赖第三方容器的基础上,如何实现动态代理就成了一个问题。

.net core依赖注入实现动态代理

我们知道,要创建一个代理对象,需要简单的三步:

  • 创建target
  • 创建interceptor
  • 使用target和interceptor创建代理对象

.net core的依赖注入允许我们自定义servicedescriptor对象,而在servicedescriptor对象中,我们可以定义对象实例化的过程,这个过程叫做factory,通过自定义factory,我们可以类型的动态代理的创建。

代码如下:

services.addtransient<logginginterceptor>();
services.addtransient<sampleservice>();

services.addtransient<isampleservice>(provider =>
{
    var target = provider.getservice<sampleservice>();
    var logginginterceptor = provider.getservice<logginginterceptor>();
    var proxy = dynamicproxyextensions.generator.createinterfaceproxywithtarget<isampleservice>(target, logginginterceptor);

    return proxy;
});

或者通过实例化servicedescriptor的方式进行注入:

services.addtransient<logginginterceptor>();
services.addtransient<sampleservice>();

func<iserviceprovider, object> factory = (provider) => {
    var target = provider.getservice<sampleservice>();
    var logginginterceptor = provider.getservice<logginginterceptor>();
    var auditinterceptor = provider.getservice<auditinterceptor>().tointerceptor();
    var proxy = dynamicproxyextensions.generator.createinterfaceproxywithtarget<isampleservice>(target, logginginterceptor, auditinterceptor);

    return proxy;
};
var servicedescriptor = new servicedescriptor(typeof(isampleservice), factory, servicelifetime.transient);

services.add(servicedescriptor);

通过这种方式,我们可以将动态代理与依赖注入结合起来。但是这样的代码缺少封装,开发效率偏低,在使用过程中还需要对依赖注入、动态代理都有一定了解,为了解决这些问题,我们需要再次封装。

依赖注入与动态代理的简单封装

public static class dependencyinjectionextensions
{
    public static iservicecollection addservice<tservice, timplementation>(this iservicecollection services,
        servicelifetime lifetime, params type[] interceptortypes)
    {
        return services.addservice(typeof(tservice), typeof(timplementation), lifetime, interceptortypes);
    }

    public static iservicecollection addservice(this iservicecollection services, type servicetype, type impltype,
        servicelifetime lifetime, params type[] interceptortypes)
    {
        services.add(new servicedescriptor(impltype, impltype, lifetime));
        
        func<iserviceprovider, object> factory = (provider) =>
        {
            var target = provider.getservice(impltype);

            list<iinterceptor> interceptors = interceptortypes.tolist().convertall<iinterceptor>(interceptortype =>
            {
                return provider.getservice(interceptortype) as iinterceptor;
            });

            var proxy = dynamicproxyextensions.generator.createinterfaceproxywithtarget(servicetype, target, interceptors.toarray());

            return proxy;
        };
        var servicedescriptor = new servicedescriptor(servicetype, factory, lifetime);
        services.add(servicedescriptor);

        return services;
    }
}

在使用时需要注意,一定要先将interceptor类注入到容器中。