设为首页 加入收藏

TOP

设计一下类似SpringIoC的注入工具~Lind.DI(一)
2019-09-17 19:07:06 】 浏览:64
Tags:设计 类似 SpringIoC 注入 工具 Lind.DI

通过注解(特性)的方式进行对象的注册与注入,方便,灵活!

  • 本篇主要讲如何去实现,下一篇主要讲如何把它集成到mvc和api环境里,实现自动的注入!

    spring ioc工作的过程大致为,统一的注册组件,拦截当前请求,统一的注入当前请求所需要的组件,事实上,说到这事,.net也完全可以实现这个功能和工作方式,下来大叔来实现一下

  1. 定义组件注册特性
  2. 定义组件生命周期
  3. 定义组件注入特性
  4. 定义Ioc工厂
  5. 使用灵活方便
  6. 将注入功能集成到mvc的拦截器里

定义组件注册特性

定义在类身上

    /// <summary>
    /// 注册组件特性.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    public class ComponentAttribute : Attribute
    {
        public LifeCycle LifeCycle { get; set; } = LifeCycle.CurrentScope;

        public String Named { get; set; }
    }

定义组件生命周期

    /// <summary>
    /// 组件生命周期
    /// </summary>
    public enum LifeCycle
    {
        CurrentScope,
        CurrentRequest,
        Global,
    }

定义组件注入特性

定义在字段上

    /// <summary>
    /// 注入一对象.
    /// </summary>
    [AttributeUsage(AttributeTargets.Field)]
    public class InjectionAttribute : Attribute
    {
        public string Named{get;set;}
    }

定义Ioc工厂

    /// <summary>
    /// DI工厂.
    /// </summary>
    public class DIFactory
    {

        static IContainer container;

        /// <summary>
        /// 手动注入.
        /// </summary>
        /// <returns>The resolve.</returns>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public static T Resolve<T>()
        {
            if (container == null)
                throw new ArgumentException("please run DIFactory.Init().");
            return container.Resolve<T>();
        }

        /// <summary>
        /// 手动注入.
        /// </summary>
        /// <returns>The by named.</returns>
        /// <param name="named">Named.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public static T ResolveByNamed<T>(string named)
        {
            if (container == null)
                throw new ArgumentException("please run DIFactory.Init().");
            return container.ResolveNamed<T>(named);
        }


    /// <summary>
        /// 把对象里的Inject特性的对象注入.
        /// web环境下,应该使用filter拦截器将当前控制器传传InjectFromObject去注入它.
        /// </summary>
        /// <param name="obj">Object.</param>
        public static void InjectFromObject(object obj)
        {
            if (obj.GetType().IsClass && obj.GetType() != typeof(string))
                foreach (var field in obj.GetType().GetFields(
                    BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public))
                {
                    if (field.GetCustomAttributes(false).Select(i => i.GetType())
                    .Contains(typeof(InjectionAttribute)))
                    {
                        InjectionAttribute inject = (InjectionAttribute)field.GetCustomAttributes(false).FirstOrDefault(i => i.GetType() == typeof(InjectionAttribute));
                        if (inject != null && !String.IsNullOrWhiteSpace(inject.Named))
                        {
                            field.SetValue(obj, container.ResolveNamed(inject.Named, field.FieldType));
                        }
                        else
                        {
                            field.SetValue(obj, container.Resolve(field.FieldType));
                        }
                        //递归处理它的内部字段
                        InjectFromObject(field.GetValue(obj));
                    }

                }
        }

        /// <summary>
        /// 初始化.
        /// </summary>
        public static void Init()
        {
            var builder = new ContainerBuilder();
            var arr = AppDomain.CurrentDomain.GetAssemblies().Where(
                 x => !x.FullName.StartsWith("Dapper")
                 && !x.FullName.StartsWith("System")
                 && !x.FullName.StartsWith("AspNet")
                 && !x.FullName.StartsWith("Microsoft"))
                 .SelectMany(x => x.DefinedTypes)
                 .Where(i => i.IsPublic && i.IsClass)
                 .ToList();
            foreac
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C# ASP.NET MVC:使用Cookie记住账.. 下一篇MyDAL - .UpdateAsync() 之 .SetS..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目