zoukankan      html  css  js  c++  java
  • 在ServiceStack服务中使用MEF容器

    1.ServiceStack服务拥有自身的容器—Funq.Container

    当我们使用接口注入的方式调用底层方法时,我们需要在AppHost中重写Configure(Funq.Container container)方法,在方法中添加container.RegisterAutoWiredAs<T, TAs>()配置,才能在服务中使用构造函数注入方式调用接口。代码示例如下:

    AppHost.cs:

    public class AppHost : AppHostBase
        {
            public AppHost() //Tell ServiceStack the name and where to find your web services
                : base("OAuth2 Demo Resource Server", typeof(UserService).Assembly) { }
    
            public override void Configure(Funq.Container container)
            {
                //Set JSON web services to return idiomatic JSON camelCase properties
                ServiceStack.Text.JsConfig.EmitCamelCaseNames = true;
    
                //Configure User Defined REST Paths
                Routes
                  .Add<Users>("/users")
                  .Add<Users>("/users/{Username}");
    
                //Register all your dependencies
    
                container.RegisterAutoWiredAs<FakeUserStore, IUserStore>();
            }
        }

    UserService.cs

    public class UserService : Service {
            private readonly IUserStore userStore;
    
            public UserService(IUserStore userStore) {
                this.userStore = userStore;
            }
    
            public User Any(Users users) {
                if (HttpContext.Current.User.Identity.Name != users.Username) {
                    throw (new UnauthorizedAccessException(String.Format("Your access token doesn't grant access to information for the user named {0}", users.Username)));
                }
                return (userStore.GetUser(users.Username));
            }
        }

    缺点:每个接口都需要添加container.RegisterAutoWiredAs<T, TAs>()配置来实例化接口,太过繁琐。

    2.ServiceStack服务调用MEF组合容器—CompositionContainer

    MEF 提供一种通过“组合”隐式发现组件的方法。 MEF 组件(称为“部件-Part”)。部件以声明方式同时指定其依赖项(称为“导入-Import”)及其提供的功能(称为“导出-Export”)。MEF原理上很简单,找出有共同接口的导入、导出。然后找到把导出的实例化,赋给导入。说到底MEF就是找到合适的类实例化,把它交给导入。

    当我们在ServiceStack中调用MEF容器时,我们就可以使用组合容器通过目录搜索组件的定义。步骤如下

    2.1 自定义一个IContainerAdapter适配器

    using ServiceStack.Configuration;
    using System.ComponentModel.Composition.Hosting;
    
    namespace OAuthStack.DataServer.Infrastructure
    {
        internal class MefIOCAdapter : IContainerAdapter
        {
            private readonly CompositionContainer _container;
    
            internal MefIOCAdapter(CompositionContainer container)
            {
                _container = container;
            }
    
            public T TryResolve<T>()
            {
                return _container.GetExportedValueOrDefault<T>();
            }
    
            public T Resolve<T>()
            {
                return _container.GetExportedValue<T>();
            }
        }
    }

    2.在AppHost中重写Configure(Funq.Container container)方法,注册MefIOCAdapter适配器

    using OAuthStack.DataServer.Services;
    using ServiceStack.ServiceInterface.Cors;
    using ServiceStack.WebHost.Endpoints;
    using System.ComponentModel.Composition.Hosting;
    using System.Web.Hosting;
    
    namespace OAuthStack.DataServer.Infrastructure
    {
        public class AppHost : AppHostBase
        {
            public AppHost()
                : base("OAuth2 Demo Resource Server", typeof(EquipmentService).Assembly) { }
    
            public override void Configure(Funq.Container container)
            {
                //Set JSON web services to return idiomatic JSON camelCase properties
                ServiceStack.Text.JsConfig.EmitCamelCaseNames = true;
                //配置跨域
                Plugins.Add(new CorsFeature());
                //注册用户认证证书
                
    
                string directoryName = System.AppDomain.CurrentDomain.BaseDirectory.ToString() + "bin\";
                AggregateCatalog aggregateCatalog = new AggregateCatalog();
                if (directoryName != null)
                {
                    //DirectoryCatalog 在指定的目录发现部件。
                    aggregateCatalog.Catalogs.Add(new DirectoryCatalog(directoryName, "Service*"));
    aggregateCatalog.Catalogs.Add(new DirectoryCatalog(directoryName, "Persistance.dll")); } CompositionContainer _mefContainer
    = new CompositionContainer(aggregateCatalog); container.Adapter = new MefIOCAdapter(_mefContainer); } } }

    Service.cs

     public class TService : Service
        {
            private readonly ITDao _tDao;
    
            [ImportingConstructor]
            public TService(ITDao tDao)
            {
                _tDao = tDao;
            }
    }

    优点:无需逐个配置接口实例化,充分利用MEF导入—导出的优点。

     
  • 相关阅读:
    shell bash memo
    python performance measure 02
    跨域的几种方法
    表示集合的数据结构:数组(Array),对象(Object),Map和Set
    [H5]range对象的setStart/setEnd方法
    文件上传:input file FileReader
    localStorage,sessionStorage,cookie使用场景和区别
    设置获取cookie,setCookie,getCookie
    js中__proto__, property, prototype, 对象自身属性方法和原型中的属性方法的区别
    使用正则表达式--切分字符串
  • 原文地址:https://www.cnblogs.com/talents/p/5278231.html
Copyright © 2011-2022 走看看