簡體   English   中英

具有動態類型的Activator.CreateInstance

[英]Activator.CreateInstance with dynamic Type

我認為我缺乏理解,究竟發生了什么:用戶可以輸入程序集的路徑和對象類型,我嘗試創建它的實例。

我的方法:

        Assembly a = Assembly.LoadFile(txtAssemblyPath.Text);
        Type myType = a.GetTypes().ToList().FirstOrDefault(f => f.Name == txtObjectName.Text);

        var obj = Activator.CreateInstance<myType>();
        var obj2 =(myType) Activator.CreateInstance(myType);

問題在於創建對象本身。 似乎myType沒有作為Type進行威脅。 在這個例子中: 從類型創建泛型變量 - 如何? 或者使用帶有屬性{}而不是參數()的Activator.CreateInstance()?

他們只是得到一個對象,所以我猜這不是同一個案例。 我根本不理解:CreateInstance(Type)可以工作,但是Type的CreateInstance沒有,但是T和Type應該是相同的:System.Type。

在此先感謝您的澄清。

馬蒂亞斯

有一個使用差異...當你寫:

var obj = Activator.CreateInstance<myType>();

您使用類似類型的類,這是實現它的好方法。 您使用了具有類類型引用的泛型類型。

但那里:

var obj2 =(myType) Activator.CreateInstance(myType);

你使用類就像一個實例(對象)。 你不能這樣做,一個類是一個模式。 如果要調用第二種方法,則必須編寫:

var obj2 =(myType) Activator.CreateInstance(typeof(myType));

此代碼將創建類Type的實例,此實例將描述您的類myType。

我希望能夠清楚。

類是一個模式,您可以使用此模式創建一個對象,它將是一個實例(您的類的內存對象)。

當您使用泛型類型的方法,如Activator.CreateInstance<T>(); 你必須提供強類型的T.這意味着你必須傳遞已知的類型名稱而不是T.例如:

var activatorPerson = (Person)Activator.CreateInstance<Person>();

這就是為什么有一個非泛型形式Activator.CreateInstance(typeGoesHere)函數,它可以在我們在創建對象時沒有強類型的情況下使用。 所以我們可以將type作為參數傳遞給該函數。 我們可以通過多種方式提供類型變量。 在您的情況下,您可以在程序集中找到正確的類型,如下所示:

Type myType = a.GetTypes().ToList().FirstOrDefault(f => f.Name == txtObjectName.Text);

你也必須注意到你在代碼中輸入的顯式轉換是無效的:

obj2 =(myType) Activator.CreateInstance(myType);

因為您必須為顯式轉換提供強類型名稱。 當我們在運行時無法訪問強類型名稱時,我們必須使用非泛型版本的方法。

這是純粹的動態方式。

這是工廠類和動態實例創建方法:

    public class RepositoryFactory
{
    public static dynamic CreateDynamic<TEntity>() where TEntity : BaseEntity
    {
        dynamic repositoryInstance = null;
        var subRepositories = AssemblyHelper.GetSubclassesOf(typeof(BaseRepository<TEntity>), true);
        var entityTypeName = typeof(TEntity).Name;
        var subRepository = subRepositories.FirstOrDefault(x => x.Name == entityTypeName + "Repository");
        if (subRepository != null)
        {
            var repositoryType = subRepository.UnderlyingSystemType;
            repositoryInstance = Activator.CreateInstance(repositoryType);
        }
        return repositoryInstance;
    }
}

這是在Entity和Repository之間映射類型的幫助器類。

public static class AssemblyHelper
{
        public static List<Type> GetSubclassesOf(Type type, bool ignoreSystem)
        {
            List<Type> lReturn = new List<Type>();
            foreach (var a in System.Threading.Thread.GetDomain().GetAssemblies())
            {
                if (ignoreSystem && a.FullName.StartsWith("System."))
                {
                    continue;
                }
                foreach (var t in a.GetTypes())
                {
                    if (t.IsSubclassOf(type) || (type.IsInterface && t.GetInterfaces().FirstOrDefault(e => e.FullName == type.FullName) != null))
                    {
                        lReturn.Add(t);
                    }
                }
            }
            return lReturn;
        }
}

這是用例的Manager類:

public class PageManager
{
    private readonly ContentPageRepository _pageRepository;
    public PageManager()
    {
        _pageRepository = RepositoryFactory.CreateDynamic<ContentPage>();
    }

    public void GetPagesByContentType(ContentType type)
    {
        var pages = _pageRepository.GetByPredicate(x => x.Status != EntityStatus.Deleted && x.Node.Type == type);
        foreach (var page in pages)
        {
            //Deal with it :)
        }

    }
}

暫無
暫無

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

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