簡體   English   中英

是否可以使用Activator.CreateInstance()使用參數構造函數創建泛型工廠?

[英]Is it possible to create a generic factory with constructor with parameters using Activator.CreateInstance()?

當它返回的類需要構造函數中的參數時,有什么方法可以實現泛型工廠? 我所有的工廠都是這樣的:

public static class UserServiceFactory
{
    public static UserService GetService()
    {
        UserRepository userRepository = new UserRepository();
        return new UserService(userRepository);
    }

}

我嘗試過這樣的事情:

 public static TServiceClass GetService<TServiceClass>()
        where TServiceClass : class, new()
    {
        TServiceClass serviceClass = null;

        string repositoryName = typeof (TServiceClass).ToString().Replace("Service", "Repository");
        Type type = Type.GetType(repositoryName);

        if (type != null)
        {
            object repository = Activator.CreateInstance(type);
            serviceClass =  (TServiceClass)Activator.CreateInstance(typeof (TServiceClass), new[]{repository});
        }

        return serviceClass;
    }

但是,這當然是行不通的,因為我不能使用沒有無參數構造函數的類作為泛型參數,但是我感覺自己很親密。 我曾考慮過傳遞諸如GetService(Type serviceClassType)類的Service類,但是后來我無法聲明該方法的返回類型,因此在調用它時必須將其強制轉換,這是我想避免的。

還有其他方法嗎? 這有可能嗎?

您可以執行以下操作,並將兩種類型都用作類型參數:

public static TService GetService<TRepository, TService>() where TRepository:new()
{
    var repository = new TRepository();
    return (TService)Activator.CreateInstance(typeof(TService), repository);
}

或者,如果您想依靠服務和存儲庫名稱相同的約定(僅用於說明):

public static TService GetService<TService>()
{
    var repositoryName = String.Concat(typeof(TService).Namespace, Type.Delimiter, typeof(TService).Name.Replace("Service", "Repository"));
    object repository = Activator.CreateInstance(Type.GetType(repositoryName));
    return (TService)Activator.CreateInstance(typeof(TService), repository);
}

這感覺並不明顯和不直觀,也許有更好,更強大的解決方案可用。

也許使用控制容器倒置將是更好的方法。

使用容器,我只需解析UserService然后讓容器注入適當的存儲庫。 如果UserService是其他方面的依賴關系,請讓DI容器解決該問題,而現代容器將解決依賴關系的依賴關系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM