zoukankan      html  css  js  c++  java
  • MEF IOC使用

    IOC介绍

    IOC:控制反转,DI:依赖注入。按我的理解应该是一个东西。作用目前我看到的主要是解除各个层之间的强耦合,实现接口分离。MEF优点:

    1、net4 自带,无需安装扩展(引用System.ComponentModel.Composition.dll)。

    2、0配置:这一点很重要,其实很早以前我就看到过IOC的介绍,但一直没搞明白怎么用(配置太多了),有什么用(虽然介绍了,但是看别人写的代码感觉比直接new还麻烦。),最开始还是在spring中看到的。

    使用方法举例

    1、DAL中使用接口隔离并导出实现类,注意:一个接口只能有一个实现类,接口代码如下:

        public interface IUserRepository
        {
            List<UserInfo> GetAllUsers();
        }

    2、实现接口,并导出为IUserRepository,为了规范代码,防止BLL中出现 IUserRepository repository=new UserRepository();之类的代码,将类改为internal,而不是public。代码如下:

     [Export(typeof(IUserRepository))]
        internal class UserRepository : MEFDemo.DAL.IUserRepository
        {
            public List<UserInfo> GetAllUsers()
            {
                List<UserInfo> listUsers = new List<UserInfo>()
                {
                    new Model.UserInfo(){UserName="奥巴马",Password="123456"},
                    new Model.UserInfo(){UserName="邓小平",Password="123456"}
                };
                return listUsers;
            }
        }

    3、在BLL中使用,类上标记为Export,需要注入的属性标记为Import。(属性,Java中成为注解)

    [Export(typeof(IUserService))]
        internal class UserSerVice : IUserService
        {
            [Import]
            protected IUserRepository UserRepository { get; set; }
    
            public List<Model.UserInfo> GetAllUsers()
            {
    
                return UserRepository.GetAllUsers();
            }
    
            public Model.UserInfo ValidateUser(string userName, string password)
            {
    
                return UserRepository.GetAllUsers().Where(m => m.UserName == userName && m.Password == password).FirstOrDefault();
            }
    
    
        }

    4、最后这是最关键的一步:

     a、MVC,分两步,第一步实现IDependencyResolver接口,代码如下:

        public class MefDependencySolver : IDependencyResolver
        {
            private readonly ComposablePartCatalog _catalog;
            private const string HttpContextKey = "MefContainerKey";
    
            public MefDependencySolver(ComposablePartCatalog catalog)
            {
                _catalog = catalog;
            }
    
            public CompositionContainer Container
            {
                get
                {
                    if (!HttpContext.Current.Items.Contains(HttpContextKey))
                    {
                        HttpContext.Current.Items.Add(HttpContextKey, new CompositionContainer(_catalog));
                    }
                    CompositionContainer container = (CompositionContainer)HttpContext.Current.Items[HttpContextKey];
                    HttpContext.Current.Application["Container"] = container;
                    return container;
                }
            }
    
            #region IDependencyResolver Members
    
            public object GetService(Type serviceType)
            {
                string contractName = AttributedModelServices.GetContractName(serviceType);
                return Container.GetExportedValueOrDefault<object>(contractName);
            }
    
            public IEnumerable<object> GetServices(Type serviceType)
            {
                return Container.GetExportedValues<object>(serviceType.FullName);
            }
    
            #endregion
        }

    第二步,在Global类的Application_Start中注册,代码如下:

                DirectoryCatalog catalog = new DirectoryCatalog(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath);
                MefDependencySolver solver = new MefDependencySolver(catalog);
                DependencyResolver.SetResolver(solver);

    b、如果是在单元测试或者应用程序中使用,需要按以下代码来调用,注意 仅仅是最后一层需要手动的用注入容器构造服务层(最后一层)的对象实例

     [Export]
        [TestClass()]
        public class UserSerViceTests
        {
    
            public UserSerViceTests()
            {
                AggregateCatalog catalog = new AggregateCatalog();
                catalog.Catalogs.Add(new DirectoryCatalog(Directory.GetCurrentDirectory()));
                catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
                CompositionContainer container = new CompositionContainer(catalog);
    
                UserService = container.GetExportedValue<IUserService>();
            }
            protected IUserService UserService { get; set; }
            [TestMethod()]
            public void ValidateUserTest()
            {
                UserInfo user = UserService.ValidateUser("admin", "123456");
                Assert.IsNull(user);
            }
    
            [TestMethod()]
            public void GetAllUsersTest()
            {
    
                List<UserInfo> listUsers = UserService.GetAllUsers();
                Assert.IsFalse(listUsers.Count < 1);
            }
        }

     最后说明一点,MEF如果有一个地方注入失败,将导致所有的注入都不可用。查找错误的方法请参照微软官方文档。

    本文代码来源于http://www.cnblogs.com/guomingfeng/archive/2013/05/19/mvc-overall-design.html,非常的深入浅出,以前总看得云里雾里的,现在基本上知道怎么用了,非常感谢作者的分享。有空我也转载一下作者这个系列的博文。

  • 相关阅读:
    Codeforces Round #657 (Div. 2) 题解
    洛谷 P2765 魔术球问题 (最小路径覆盖 or 贪心)
    洛谷 P2472 蜥蜴 (最大流)
    Codeforces Round #665 (Div. 2) 题解
    洛谷 P1231 教辅的组成 (三分图匹配,裂点)
    USACO5.4 奶牛的电信Telecowmunication (最小割,割边转割点)
    有关网络流的一些板子题
    洛谷 p2756 飞行员配对方案问题(最大流,二分图匹配)
    JSON.toJSONString中序列化空字符串遇到的坑
    关于mysql自动备份的小方法
  • 原文地址:https://www.cnblogs.com/shya/p/4574450.html
Copyright © 2011-2022 走看看