1.ServiceStack服務擁有自身的容器—Funq.Container 當我們使用介面註入的方式調用底層方法時,我們需要在AppHost中重寫Configure(Funq.Container container)方法,在方法中添加container.RegisterAutoWiredAs<T,
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導入—導出的優點。