2014-06-19 126 views
1

我創建了一個項目來了解Windsor城堡和單身人士。要做到這一點,我有以下代碼使用具有依賴注入的單例(Castle Windsor)

控制器:

public class AdminController : Controller 
{ 
    private readonly IOfflineUserService _offlineUser; 
    public AdminController() 
    { 
     _offlineUser = OfflineUserService.instance; 
    } 
    [OutputCache(Duration = 20, VaryByParam = "none", Location = OutputCacheLocation.Server, NoStore = true, SqlDependency = "Default:Admin")] 
    public ActionResult test() 
    { 
     var data = _offlineUser.GetAllOfflineUsers(); 
     return View(data); 
    } 
} 

辛格爾頓的基類:

public abstract class SingletonBase<T> where T : class 
    { 
    #region Members 

    /// <summary> 
    /// Static instance. Needs to use lambda expression 
    /// to construct an instance (since constructor is private). 
    /// </summary> 
    private static readonly Lazy<T> sInstance = new Lazy<T>(() => CreateInstanceOfT()); 

    #endregion 

    #region Properties 

    /// <summary> 
    /// Gets the instance of this singleton. 
    /// </summary> 
    public static T Instance { get { return sInstance.Value; } } 

    #endregion 

    #region Methods 

    /// <summary> 
    /// Creates an instance of T via reflection since T's constructor is expected to be private. 
    /// </summary> 
    /// <returns></returns> 
    private static T CreateInstanceOfT() 
    { 
     return Activator.CreateInstance(typeof(T), true) as T; 
    } 

    #endregion 
} 

服務類:

public class OfflineUserService : SingletonBase<OfflineUserService>,IOfflineUserService 
{ 

    private readonly IUnitOfWork _unitOfWork; 
    private readonly IUserRepository _userRepository; 
      private readonly IAdminRepository _adminRepository; 

    public OfflineUserService() 
    { 

    } 

    public OfflineUserService(IUnitOfWork unitOfWork, 
     IUserRepository userRepository, 
     IAdminRepository adminRepository, 
     ) 
    { 
     _adminRepository = adminRepository; 
     _unitOfWork = unitOfWork; 
     _userRepository = userRepository; 

    } 
    public List<OfflineUsers> GetAllOfflineUsers() 
    { 
    //Some Code 
    } 
} 

所以在控制器強似OfflineUserService .instance;我想通過IOfflineUserService.instance以便我可以使用它。我不知道如何做到這一點。如果我通過它通過構造函數依賴注入工作正常

public AdminController(IOfflineUserService offlineUser) 
    { 
     _offlineUser = offlineUser; 
    } 

但我想用單所以要實現這一點,我可以創建實例作爲代碼提及,但我不知道如何創建單一個接口的實例。請建議如果我做錯了什麼,因爲我正在試圖瞭解這種行爲,以便我可以開始在項目中使用它。

回答

4

抱歉,但似乎你正在做的事情非常錯誤的...

當你僱用你的項目的IoC容器,你必須讓他做自己的工作:創建實例,任何實例必須創建/通過發佈該容器(RRR pattern)。沒有例外(當然,因爲甚至沒有在容器中註冊,所以排除了數據/模型類)。

在你的情況下,你不需要SingletonBase:容器會爲你完成這項工作。您只需註冊您的組件OfflineUserService並告訴到具有作爲一個Singleton

container.Register(
Component 
.For<IOfflineUserService>() 
.ImplementedBy<OfflineUserService>() 
.LifestyleSingleton()) 

要管理的容器當心你的樣品製作very bad hierarchy error

您的服務(OfflineUserService)取決於在另一個UnitOfWork組件上,它通常應該有一個PerWebRequest生活方式(在一個web應用程序中)。如果OfflineUserService會被Singleton攻擊,UnitOfWork實例最終會變成一個「單身人士」......只要你把你的代碼放在prod中就會成爲你最糟糕的噩夢:)

+0

Thanx很多!!!!但我已經註冊的UnitOfWork爲Component.For () .ImplementedBy () .LifeStyle.PerWebRequest,所以它仍然會被視爲單????? –

+0

是的,它會......實例是單例實例(OfflineUserService)的依賴。仔細閱讀關於俘虜依賴的ploeh文章...作爲解決方法,您應該有一個工廠(TypedFactory請參閱windsor維基)作爲您的單例(OfflineUserService)的依賴關係:工廠將根據組件註冊 – Crixo

+0

創建實例Thanx很多!我會重新考慮我的設計模式。 –

0

嘗試,如果你能創造財產您的接口獲得實例是這樣的:

public interface IOfflineUserService<T> where T : class 
{ 
    T GetServiceInstance { get; } 
} 

雖然在你的類實現通過此屬性返回實例:

public class OfflineUserService : SingletonBase<OfflineUserService>,IOfflineUserService<OfflineUserService> 
{ 
    public OfflineUserService GetServiceInstance 
    { 
     get { 
       return Instance; 
      } 
    } 
} 

然後你就可以訪問它在具有依賴注入的控制器中。

相關問題