基於AspectCore打造屬性注入



 

前言

源自於曉晨在成都.net社區群的一篇文章 《曉晨的ASP.NET Core 奇淫技巧之偽屬性注入》

他的思路是 Ioc容器替換 ControllerActivator,因為只能在控制器內完成屬性注入,意識心癢癢,就開筆寫了這樣一篇

先分析一下屬性注入的思路

屬性注入的核心就是通過動態代理完成注入,在這個過程中,對源實例的屬性/字段注入實體

想了一下,最近幾天沉迷學習,沒有寫點什么技術分享了,又想起之前學習AspectCore的過程,就打算基於AspectCore制作屬性注入


 

設計思路如下

可以看見無論是默認的特性注入AOP流程,還是我們自定義的代理工廠類,核心都是通過攔截執行過程到自定義的過濾器

個人選擇實現的方式是自定義工廠類,也可以根據代碼,實現特性注入的方式注入屬性

到屬性注入這一步,就是查找自定義的特性,有注入的特性的,則完成字段/屬性注入


 

實例實現

屬性注入的特性

    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
    public class PropertyInjectAttribute: Attribute
    {

    }

這個特性,我們約束了只能打在字段/屬性上面

自定義過濾器/過濾器工廠類

過濾器

    internal class PropertyInjectInterceptor : IInterceptor
    {
        public bool AllowMultiple => true;

        public bool Inherited { get ; set; }
        public int Order { get; set; }

        public Task Invoke(AspectContext context, AspectDelegate next)
        {
            var instace = context.Implementation;
            var instanceType = instace.GetType();

            var serviceProvider = context.ServiceProvider;

            var bindingFlag = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;

            foreach (var field in instanceType
                        .GetFields(bindingFlag)
                        .Where(_field =>
                            _field.GetCustomAttributes(typeof(PropertyInjectAttribute), true) != null &&
                            _field.GetCustomAttributes(typeof(PropertyInjectAttribute), true).Length > 0 &&
                            _field.FieldType.IsInterface
                        )
            )
            {
                var value = field.GetReflector().GetValue(instace);

                if (value == null)
                {
                    var service = serviceProvider.GetRequiredService(field.FieldType);

                    field.GetReflector().SetValue(instace, service);
                }
            }

            foreach (var property in instanceType
                        .GetProperties(bindingFlag)
                        .Where(_property =>
                            _property.GetCustomAttributes(typeof(PropertyInjectAttribute), true) != null &&
                            _property.GetCustomAttributes(typeof(PropertyInjectAttribute), true).Length > 0 &&
                            _property.PropertyType.IsInterface
                        )
            )
            {
                var value = property.GetReflector().GetValue(instace);

                if (value == null)
                {
                    var service = serviceProvider.GetRequiredService(property.PropertyType);

                    property.GetReflector().SetValue(instace, service);
                }
            }

            return next(context);
        }
    }

過濾器工廠類

    public class PropertyInjectInterceptorFactory : InterceptorFactory
    {
        public override IInterceptor CreateInstance(IServiceProvider serviceProvider)
        {
            return serviceProvider.GetRequiredService<PropertyInjectInterceptor>();
        }
    }

 

啟用過濾器工廠類

            services.AddScoped<PropertyInjectInterceptor>();
            services.ConfigureDynamicProxy(config =>
            {
                config.Interceptors.Add(new PropertyInjectInterceptorFactory());
            });

            return services.BuildDynamicProxyProvider();

編寫測試例子

    public interface IInterface
    {
        void Hello();
    }

    internal class InterfaceService : IInterface
    {
        [PropertyInject]
        private IPropertyServer propertyServer;

        [PropertyInject]
        private IPropertyServer _propertyServer { get; set; }

        public void Hello()
        {
            Console.WriteLine("Hello");
        }
    }

    [NonAspect]
    public interface IPropertyServer
    {

    }

    internal class PropertyServer: IPropertyServer
    {

    }

屬性注入的實現,我不想再被AOP代理一次,就打上了NopAspect特性,如果不介意的話,也可以不打

 


后話

我隱隱約約記得AspectCore是自帶了屬性注入的,奈何最近幾天沒寫C#代碼了,有點想念,就自己擼上,重復造輪子了

分享嘛,思路最重要,使用而言,有成熟的輪子肯定不要自己造,學習的話,就要有勇於造輪子的心思

 

打個小廣告

如果有技術交流可以加NCC的群 24791014、436035237,我在群里,有任何關於asp.net core方面的問題或者建議都可以與我交流,非常歡迎

 

附上曉晨的鏈接

《ASP.NET Core 奇淫技巧之偽屬性注入》

https://www.cnblogs.com/stulzq/p/12610026.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM