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