2009-12-10 98 views
2

統一框架,這樣的故事是這樣的:與配置文件和單類

我有單獨的類(a.k.a服務定位器),你可以得到使用「的CreateInstance()」方法的實例。同時,我們將Unity添加到我們的應用程序中,並使用標準配置文件對其進行配置。

當我試圖映射接口IServiceLocator以獲取ServiceLocator的實例並將其註冊到統一配置文件中時,問題就開始了。正如你可能猜測,服務定位器沒有一個公共的構造(即單),因此,統一不能創建它,當我做unity.resolve<IServiceLocator>() ....

我的問題:有沒有辦法告訴團結(通過配置文件)使用CreateInstance()而不是嘗試執行默認構造函數?如果沒有,如果你有其他想法還有什麼可以做的,我希望聽到它。

請不要建議我將構造函數更改爲public,假設我現在不能這樣做。

回答

0

你最好手動創建UnityContainer並將它注入到你的服務定位:

public class ServiceLocator 
{ 
    public static void SetServiceLocatorProvider(IServiceLocator serviceLocator) 
    { 
     Instance = serviceLocator; 
    } 

    public static void SetServiceLocatorProvider(Func<IServiceLocator> serviceLocator) 
    { 
     Instance = serviceLocator(); 
    } 

    public static IServiceLocator Instance { get; private set; } 
} 


public class ServiceLocatorContainer : IServiceLocator 
{ 
    private readonly IUnityContainer _unityContainer; 

    public ServiceLocatorContainer(IUnityContainer unityContainer) 
    { 
     _unityContainer = unityContainer; 
    } 
//skipped for simplicity sake 
} 


    public abstract class ApplicationControllerBase 
    { 


     /// <summary> 
     /// Создать экземпляр Unity контейнера 
     /// </summary>   
     private IUnityContainer CreateContainer() 
     { 
      return new UnityContainer(); 
     } 

     protected virtual void ConfigureContainer() 
     { 

      RegisterTypeIfMissing(typeof(IServiceLocator), typeof(ServiceLocatorContainer), true); 
      RegisterTypeIfMissing(typeof(ISharedAssemblyInitializer), typeof(SharedAssemblyInitializer), true); 

      ServiceLocator.SetServiceLocatorProvider(() => this.Container.Resolve<IServiceLocator>()); 

     } 


    protected void RegisterTypeIfMissing(Type fromType, Type toType, bool registerAsSingleton) 
    { 

     if (Container.IsTypeRegistered(fromType)) 
     { 

     } 
     else 
     { 
      if (registerAsSingleton) 
      { 
       Container.RegisterType(fromType, toType, new ContainerControlledLifetimeManager()); 
      } 
      else 
      { 
       Container.RegisterType(fromType, toType); 
      } 
     } 
    } 


     public virtual void Run() 
     { 
      this.Container = CreateContainer(); 
      this.ConfigureContainer(); 
     } 

     public IUnityContainer Container { get; private set; } 
} 

這是棱鏡延伸到統一的簡化版本。請參閱棱鏡中模塊管理員類的更詳細資源。 應用程序以Run方法啓動。您創建容器並在其中註冊您的servicelocator。威樂登記,UnityContainer創建它的實例和它本身傳遞到構造函數:

public ServiceLocatorContainer(IUnityContainer unityContainer) 
{ 
    _unityContainer = unityContainer; 
} 

然後使用SetServiceLocatorProvider方法分配給服務定位器類的實例屬性例子,一個具有參考內部的團結容器。這種解決方案也提供了混凝土DI容器的抽象。你可以從代碼中的任何地方引用你的服務定位器。 1)Injectiong入構造

public class RLoginABS 
{ 

    IServiceLocator serviceLocator; 

    public RLoginABS(IServiceLocator serviceLocator) 
    { 
     this.serviceLocator = serviceLocator; 
    } 

    public void Login(string user, string password) 
    {    
     REnvironmentRWS environment = REnvironmentRWS.Current;    
     serviceLocator.RegisterInstance<IEnvironmentRWS>(environment as IEnvironmentRWS); 
    } 

} 

或使用靜態類:

shellViewModel = ServiceLocator.Instance.Resolve<IShellViewModel>(); 

PS:IServiceLocator接口,這是具體的實施DI容器的抽象:

public interface IServiceLocator 
{ 
    void Register<TInterface, TImplementor>() where TImplementor : TInterface; 
    void Register(Type TInterface, Type TImplementor); 
    void RegisterAsSingleton<TInterface, TImplementor>() where TImplementor : TInterface; 
    T Resolve<T>(); 
} 

其方法包裝混凝土容器的方法,例如:

public void Register(Type TInterface, Type TImplementor) 
{ 
    _unityContainer.RegisterType(TInterface, TImplementor); 
} 

希望 - 它有幫助!