• WebApi整合Unity容器实现IOC编程


    1管理Nuget包,引入Unity

    2定义接口和实现类

    public interface IUserService
        {
            object Query(int id);
        }
        public class UserService : IUserService
        {
            public object Query(int id)
            {
                return new
                {
                    Id = id,
                    Name = "AAA",
                    Remark = "aaa"
                };
            }
        }

    3添加配置文件Unity.Config,配置文件要设置为始终复制

    4定义创建Unity容器的工厂类

    /// <summary>
    /// 需要在nuget引用之后,单独引用Unity.Configuration
    /// 如果有AOP扩展,还需要引用Unity.Interception.Configuration
    /// 因为我们是用配置文件来做的配置
    /// </summary>
    public class ContainerFactory
    {
        public static IUnityContainer Container
        {
            get
            {
                return _Container;
            }
        }
    
        private static IUnityContainer _Container = null;
        static ContainerFactory()
        {
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\Unity.Config");//找配置文件的路径
            Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
            UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
            _Container = new UnityContainer();
            section.Configure(_Container, "WebApiContainer");//指向配置文件的container节点
        }
    }

    5使用Unity容器【通过Resolve】创建对象(一般不用这种方式)

    使用IOC要么不用要么用到底,所以不用这种方式创建对象,而是通过依赖注入的方式,看下面的第6

        public class IOCController : ApiController
        {
            public string Get(int id)
            {
    IUserService service = ContainerFactory.BuildContainer().Resolve<IUserService>();
                return Newtonsoft.Json.JsonConvert.SerializeObject(service.Query(id));
            }
        }

    6使用Unity容器【通过依赖注入】创建对象(主要用这种方式)

    这里是整合UnityWebApi,主要用这种方式。

     public class IOCController : ApiController
        {
            private IUserService _UserService = null;
            public IOCController(IUserService userService)//构造函数注入
            {
                this._UserService = userService;
            }
    
            public string Get(int id)
            {
                return Newtonsoft.Json.JsonConvert.SerializeObject(this._UserService.Query(id));
            }
        }

    将容器和WebApi整合在一起:

    因为我们在控制器的构造函数上添加了自定义参数,框架在创建控制器时调用的是无参的构造函数,这时我们定义了带参数的构造函数,所以框架创建失败,因为找不到无参构造函数,而我们又希望对参数的实例化交给容器,所以这时候我们需要将容器和WebApi整合,让它创建Controller时调用的是我们定义的容器。

    创建一个类UnityDependencyResolver,继承自IDependencyResolver接口,实现接口:

    public class UnityDependencyResolver : IDependencyResolver
    {
        private IUnityContainer _UnityContainer = null;
        public UnityDependencyResolver(IUnityContainer container)
        {
            _UnityContainer = container;
        }
    
        public IDependencyScope BeginScope()//Scope
        {
            return new UnityDependencyResolver(this._UnityContainer.CreateChildContainer());
        }
    
        public void Dispose()
        {
            this._UnityContainer.Dispose();
        }
    
        public object GetService(Type serviceType)
        {
            try
            {
                return _UnityContainer.Resolve(serviceType);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }
    
        public IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return _UnityContainer.ResolveAll(serviceType);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }
    }

    将自定义的UnityDependencyResolver,整合到WebApi中,在WebApiConfig类的Register方法中将我们自定义的Resolver覆盖框架自带的Resolver

    config.DependencyResolver=new UnityDependencyResolver(ContainerFactory.BuildContainer());

  • 相关阅读:
    Executors源码之线程池
    Java序列化对字段名的影响
    Spring Cloud Alibaba(二)
    Security版本冲突,老版本共用服务接入新版本服务
    记一次虚拟机崩溃事件和解决方法(CentOS7)
    vue-cli 项目构建学习笔记(Vue3)
    IDEA插件-IDE Eval Reset
    Docker的学习
    Spring Security的学习
    Spring MVC框架的设计理念
  • 原文地址:https://www.cnblogs.com/LJP-JumpAndFly/p/12316540.html
Copyright © 2020-2023  润新知