ASP.NET MVC dependency injection

Automatic injection function, making the code more simple and flexible java in the spring, so take that in transplanted to c #, the next step by step analysis of the implementation process

1. Automatic injection Scene Analysis

In asp.net mvc, regardless of what code is logical hierarchy, the final presentation layer for the Controller layer, so we injection point is in the Controller, where we need to replace the default target ControllerFactory, scan the code marks need to inject performs examples of implant

 public class FastControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(RequestContext requestContext, string controllerName)
        {
            Type type = this.GetControllerType(requestContext, controllerName);
            Object obj = GetControllerInstance(requestContext, type);

            //Controller中标记AutoWired属性的自动注入
            List<FieldInfo> AutoWiredFieldList = type.GetRuntimeFields().Where(f => f.GetCustomAttribute(typeof(AutoWired)) != null).ToList();
            foreach (FieldInfo field in AutoWiredFieldList)
            {
                field.SetValue(obj, InjectUtil.Container.Resolve(field.FieldType));
            }
            return obj as IController;
        }
    }

FastControllerFactory is our custom a Controller factory, override CreateController method of marking the AutoWired this argument defined annotations, examples taken from Bean container assignment, we also need the Start method in the Global file, make default plant replacement

ControllerBuilder.Current.SetControllerFactory(new FastControllerFactory());

Achieve 2.IOC container

c # custom container has a lot of mature open source frameworks such as AutoFac, etc., where we own realization is a lightweight version

Source Address: https://gitee.com/grassprogramming/FastIOC

Let us focus here on how to use asp.net mvc is, first of all we need to Bean object needs to be injected mark, the mark is called Component,

In the Start method asp.net mvc Global file, we need the entire project to be automatically injected into the vessel Bean

    public class InjectUtil
    {
        public static ContainerBuilder Container;
        public static void Init()
        {
            Container = new ContainerBuilder();
             //获取所有程序集
            var assemblies = System.Web.Compilation.BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
            //注入所有Component组件
            Container.RegisterAssemblyTypes(assemblies, typeof(Component),true);
            Container.Build();
        }
    }

 

Here matters Controller level has been completed, then you need to initialize the IOC container Bean instance method further treatment

       private Object GetInstance(RegisterEntity Entity)
        {
            Object obj = null;
            if (Entity.IsEnableIntercept)
            {
                bool IsExtend = Entity.RealType == Entity.RegistType;
                obj = DynamictProxy.CreateProxyObject(Entity.RealType, Entity.RegistType, Entity.InterceptType, IsExtend, Entity.IsInterceptAllMethod);


            }
            else
            {
                var constructors = Entity.RegistType.GetConstructors();
                obj = constructors[0].Invoke(newObject [] {}); 
            } 
            // used herein, a single instance of the embodiment mode Instance memory, advance the exposed object instance is not provided subsequent 
            IF (! ) SingleInstanceDic.ContainsKey (Entity.RealType) 
            { 
                SingleInstanceDic.Add (Entity.RealType , obj); 
            } 
        
            // if this class labeled Component, and there is a marked Field AutoWired, automatic injection 
            IF (Entity.RealType.GetCustomAttribute ( typeof (the Component), to true ) =! null ) 
            { 
                // here use GetRuntimeFields, this method returns all fields defined in the specified type, including inherited, non-public, and examples of the static field. 
                the foreach (Field, the FieldInfo in Entity.RealType.GetRuntimeFields ()) 
                {
                    IF (Field.GetCustomAttribute ( typeof (Autowired), to true !) = null ) 
                    { 
                        the Type FieldType = Field.FieldType;
                         IF (the Contains (FieldType)) 
                        { 
                            // determines whether to include a single-instance storage, if any, taken assignment, where circular dependencies can be prevented due to an infinite loop 
                            IF (SingleInstanceDic.ContainsKey (FieldType)) 
                            { 
                                Field.SetValue (obj, SingleInstanceDic [FieldType]); 
                            } 
                            the else 
                            { 
                                Field.SetValue (obj, Resolve (FieldType));
                            }
                           
                        }
                    }
                }
            }
            return obj;

        }

 

GetInstance Bean object is to instantiate the core of the method is very simple, is to create objects through reflection, of which there are two points to note

1) The need to scan all the time in a variable Bean Bean initialization, if there is internal nested object dependency injection, it is necessary to use a recursive, until there is no need to inject the Field

2) I used here is the single-mode embodiment, as there may be performed during testing of B class A dependency injection, injection of A dependency of class B, the conventional process of creating, if the scanned recursively, will into the loop, overflow of memory, the use of a single subject embodiment, it has been created into the dictionary, if the subject is scanned again to be injected, taken directly used, to avoid circular references

3. Other

Controller class are not used in other relies injection, it is necessary to use directly remove the container from the IOC Bean

 private AuthUtil @AuthUtil = InjectUtil.Container.Resolve<AuthUtil>();

Function here on all the analysis is complete, the last fight ad, write your own ASP.NET MVC framework for rapid development, we want to support the wave

Address: https://gitee.com/grassprogramming/FastExecutor

Guess you like

Origin www.cnblogs.com/yanpeng19940119/p/11502385.html