繁体   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