gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 22:12:04 24 4
gpt4 key购买 nike

我有一个包含实体的域层程序集,它被包含实体存储库实现的数据层程序集引用。在域层组件中,实体被组织在具有根实体和子实体的聚合中。我使子实体不能直接实例化,将它们的构造函数转为内部。这样客户就不能在他们身上使用新的运营商,但他们被迫使用工厂。

在数据层组件中,我为每个实体创建了一个存储库(无论它是根实体还是子实体)。存储库是使用泛型实现的,当在返回实际实体或实体列表的 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com