在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导入—导出的优点。

 

你可能感兴趣的:(在ServiceStack服务中使用MEF容器)