c# - 如何使用内部构造函数从具有新约束的泛型类创建实体

标签 c# .net generics constructor internal

我有一个包含实体的域层程序集,它由包含实体存储库实现的数据层程序集引用。在域层组件中,实体被组织在具有根实体和子实体的聚合中。我使子实体不能直接实例化,将其构造函数转换为内部构造函数。这样客户端就不能使用 new 操作符,而是被迫使用工厂。

在数据层程序集中,我为每个实体都有一个存储库(无论它是根实体还是子实体)。存储库是使用泛型实现的,当在返回实际实体或实体列表的 GetByIdGetAll 方法中时,问题就会出现。为了让他们创建新实例,我必须在泛型上指定 new() 约束。这不会编译,因为 new() 约束需要公共(public)无参数构造函数。我尝试使用internalsVisibleTo属性来允许数据层程序集访问域层内部,但它不起作用。

我没有使用EF或其他ORM,而是使用ADO.NET和一个非常简单的映射库。

这是一些示例代码:

namespace DomainLayer {

    public class Entity {

        internal Entity() {
        }      

    }

}

namespace DataLayer {

    public class Repository<T> where T: new() {

        public T GetById<T>() {
            return new T();
        }

    }

}

namespace Client {

    public class AClientClass {

        public void aMethod() {
            Entity entity1 = new Entity(); // Not possible, correct
            Entity entity2 = new Repository<Entity>().GetById(10); //Not possible, how to fix it???
        }

    }

}

我得到的编译错误是:

'DomainLayer.Entity' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'DataLayer.Repository<T>'    

非常感谢。 塞布

在重构代码下方使用 Ed_Chapel 建议:

namespace DomainLayer {

    public class Entity {

        internal Entity() {
        }      

    }

}

namespace DataLayer {

    public class Repository<T> {

        private Func<T> _creator;

        public Repository(Func<T> creator) {
            _creator = creator;
        }

        public T GetById(int id) {
            return _creator();
        }

    }
}

namespace DataLayer {
    public class EntityRepository : Repository<Entity> {

        public EntityRepository()
            : base(() => new Entity()) {
        }

    }
}

namespace Client {

    public class AClientClass {

        public void aMethod() {
            Entity entity1 = new Entity(); // Not possible, correct
            Entity entity2 = new EntityRepository().GetById(10); //Now working!!!
        }

    }

}

感谢 Ed_Chapel!

最佳答案

假设客户端没有实例化 Repository<T>并且您正在提供实例,您可以传递 Func<T>为您进行激活。

public class Repository<T> {

    private Func<T> _activator;

    internal Repository<T>(Func<T> activator) {
        _activator = activator;
    }

    public T GetById<T>() {
        return _activator();
    }
}

然后您将创建您的 Repository<T>内部。

EntityRepository = new Repository<Entity>(() => new Entity());

这里的另一个优点是,如果某些实体具有非空 .ctor,则您的 Func<T>可以容纳。

关于c# - 如何使用内部构造函数从具有新约束的泛型类创建实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19904777/

相关文章:

c# - 如何在统一重新加载场景时重新启动我的分数(重置静态分数)?

c# - 反编译导致错误CS1112,汇编困惑

将参数转换为泛型变量时的 Java 方法多态性

c# - 即使使用具有容量的构造函数,列表 C# 容量始终为 0?

c# - 基本多线程代码未按预期工作

c# - 在 Redis 中存储 Dictionary of Dictionary (StackExchange.Redis)

c# - 如何在 ASP.NET MVC 中集成 Skype for business 功能

.net - IronRuby - .NET 4.0 - 方法名称末尾的问号和感叹号

c# - 如何使用 WCF 发送用户凭据以在远程计算机上使用?

c# - 从抽象类访问泛型列表