当前位置:  开发笔记 > 编程语言 > 正文

Activator.CreateInstance与通用存储库

如何解决《Activator.CreateInstance与通用存储库》经验,为你挑选了1个好方法。

我正在尝试(我认为)一个工厂,它根据传递给方法的枚举创建一个存储库.看起来像这样:

RepositoryFactory

public class RepositoryFactory
{
    public IRepository GetRepository(FormTypes formType)
    {
        // Represents the IRepository that should be created, based on the form type passed
        var typeToCreate = formType.GetAttribute().Type;

        // return an instance of the form type repository
        IRepository type = Activator.CreateInstance(typeToCreate) as IRepository;

        if (type != null)
            return type;

        throw new ArgumentException(string.Format("No repository found for {0}", nameof(formType)));
    }
}

IRepository

public interface IRepository 
    where T : class, IEntity
{
    bool Create(IEnumerable entities);

    IEnumerable Read();

    bool Update(IEnumerable entities);

    bool Delete(IEnumerable entities);
}

FormTypes

public enum FormTypes
{
    [EnumType(typeof(Form64_9C2Repository))]
    Form64_9C2,

    [EnumType(typeof(Form64_9BaseRepository))]
    Form64_9Base
}

EnumExtensions

public static class EnumExtensions
{

    /// 
    /// Get the Enum attribute
    /// 
    /// The attribute
    /// The enum
    /// The type to create
    public static T GetAttribute(this System.Enum enumValue)
        where T : Attribute
    {
        FieldInfo field = enumValue.GetType().GetField(enumValue.ToString());
        object[] attribs = field.GetCustomAttributes(typeof(T), false);
        T result = default(T);

        if (attribs.Length > 0)
        {
            result = attribs[0] as T;
        }

        return result;
    }

}

Form64_9C2Repository

public class Form64_9C2Repository : IRepository
{
    public bool Create(IEnumerable entities)
    {
        throw new NotImplementedException();
    }

    public bool Delete(IEnumerable entities)
    {
        throw new NotImplementedException();
    }

    public IEnumerable Read()
    {
        throw new NotImplementedException();
    }

    public bool Update(IEnumerable entities)
    {
        throw new NotImplementedException();
    }
}

IEntity

public interface IEntity { }

Form64_9C2(存根)

public class Form64_9C2 : IEntity { }

将其全部称为:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Repository Factory Example \n\n");

        Business.Factory.RepositoryFactory factory = new Business.Factory.RepositoryFactory();

        // Get a 64 9C2 repository
        var repo9c2 = factory.GetRepository(FormTypes.Form64_9C2);
        Console.WriteLine(repo9c2);
    }
}

我的问题是我type一直在努力解决null.我期待得到一个NotImplementedException,但我得到的ArgumentException是没有有效的formType.

在此输入图像描述

在实现IRepository我的type/ repository成功创建之前(这里的工作代码),任何想法?我只是开始玩工厂,仿制药等等 - 所以如果我做错了什么,请指教!



1> Darin Dimitr..:

您的代码不能用于此行无法编译的完全相同的原因:

IRepository repo = new Form64_9C2Repository();

即使是工具,基本上IRepository也不一样.IRepositoryForm64_9C2IEntity

如果接口T上的泛型参数IRepositorycovariant:

public interface IRepository where T : class, IEntity
{
    IEnumerable Read();    
}

但不幸的是,这意味着它只能作为方法的返回类型出现,而不是作为参数出现.对于你和方法来说Update,这是不行的.你当然可以定义这样的结构:DeleteCreate

public interface IReadonlyRepository where T : class, IEntity
{
    IEnumerable Read();    
}

public interface IRepository: IReadonlyRepository where T : class, IEntity
{
    bool Update(IEnumerable entities);
    bool Delete(IEnumerable entities);
    bool Create(IEnumerable entities);
}

让你的GetRepository方法返回一个IReadonlyRepository.

如果这对您不起作用,您将需要一个额外的参数来指定具体的实体类型,以便您执行正确的强制转换:

    public IRepository GetRepository(FormTypes formType) where TEntity: class, IEntity
    {
        // Represents the IRepository that should be created, based on the form type passed
        var typeToCreate = formType.GetAttribute().Type;

        // return an instance of the form type repository
        IRepository type = Activator.CreateInstance(typeToCreate) as IRepository;

        if (type != null)
            return type;

        throw new ArgumentException(string.Format("No repository found for {0}", nameof(formType)));
    }
}

除了指定存储库类型之外,还需要指定实体类型:

var repo9c2 = factory.GetRepository(FormTypes.Form64_9C2);

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有