C# 从类实现的接口创建类的实例
您好,我正在尝试构建一个通用UoWFactory,它创建一个unitofwork,将有一个默认unitofwork和多个自定义实现。到目前为止,我能够创建工厂方法,该方法创建默认UoW并返回它。我修改了以下方法,根据传递的参数返回指定的UoW 当前实施C# 从类实现的接口创建类的实例,c#,.net,factory,unit-of-work,C#,.net,Factory,Unit Of Work,您好,我正在尝试构建一个通用UoWFactory,它创建一个unitofwork,将有一个默认unitofwork和多个自定义实现。到目前为止,我能够创建工厂方法,该方法创建默认UoW并返回它。我修改了以下方法,根据传递的参数返回指定的UoW 当前实施 private BaseResult<IUnitOfWork> GetUnitOfWorkByCompiledModel<IUnitOfWork>(DbCompiledModel compiledModel) {
private BaseResult<IUnitOfWork> GetUnitOfWorkByCompiledModel<IUnitOfWork>(DbCompiledModel compiledModel)
{
return new BaseResult<IUnitOfWork>
{
Payload = new DbUnitOfWork(_context, _dbRepository, _mapper, _entityMapper)
};
}
但如果我将接口类型作为参数传递,那么如何创建DbUnitOfWork或CustomUnitOfWork的实例。
例如:-
若DbUnitOfWork类具有正确的值名称,则这将有效 你想改变什么 变为 希望这能奏效。无参数构造函数 您想要的是可能的,除了一件事:您不能将非默认构造函数与泛型类型参数一起使用。你无法避免 这里的部分问题是您无法从接口强制执行特定的构造函数方法签名,因此无法保证所有IUnitOfWork实现都将具有相同的构造函数 这里最简单的解决方案是不再使用构造函数,而是使用对象初始化:
public interface IUnitOfWork
{
Foo Foo { get; set; }
}
private BaseResult<TUnitOfWork> GetUnitOfWorkByCompiledModel<TUnitOfWork>(DbCompiledModel compiledModel) where TUnitOfWork : IUnitOfWork, new()
{
return new BaseResult<TUnitOfWork>
{
Payload = new TUnitOfWork()
{
Foo = myFoo
};
};
}
这里的良好实践方法要求您在整个框架中执行此依赖项注入,因此您不需要显式调用任何构造函数,而是让DI框架为您执行此操作
可以使用,它本质上是一个您可以随意调用的DI框架。使用的一个小例子是:
private BaseResult<TUnitOfWork> GetUnitOfWorkByCompiledModel<TUnitOfWork>(DbCompiledModel compiledModel) where TUnitOfWork : IUnitOfWork, new()
{
var uow = myServiceLocator.Get<TUnitOfWork>();
uow.Foo = myFoo;
return new BaseResult<TUnitOfWork>
{
Payload = uow;
};
}
这将创建注册到要用作泛型参数的接口的任何具体类型的实例
然而,服务定位器通常被认为是一种反模式,我强烈建议您避免使用比这更干净的IoC方法
我无法在单个StackOverflow答案的范围内详细阐述依赖项注入。我建议您查找依赖项注入,因为它正是您所期望的通过引用接口获得具体类型的功能我必须从中创建实例interface@HarishNIngeGowda小心你表达你想要的东西。据我所知,您不想从接口创建实例,而是从实现所述接口的类型泛型类类型。你能发布DbUnitOfWork类吗?@Arphile:DbUnitOfWork的细节应该与知道它实现了IUnitOfWork无关,因为泛型代码应该与用作泛型类型的特定类型无关。这确实是一个很好的解决方案。但在我的场景中,它将形成一个循环依赖。即使很复杂,也有不同的方法吗?我可以拉出实现接口的类并使用反射创建实例吗。@HarishNIngeGowda:这将如何创建循环依赖关系?问题/答案中没有包含循环依赖项。有两个包1。合同包含接口和2。域包含这些接口的实现以及_context、_dbRepository、_mapper、_entityMapper。工作单位取决于合同。对于上述工作,合同应取决于域。这将使循环。我不认为这些信息与质疑有关。同样,将上下文、\u数据库存储库、\u映射器、\u entityMapper放在iUnitof Work中会将它们暴露在外部世界中,这是我不希望发生的。
GetUnitOfWorkByCompiledModel<IUnitOfWork>(compiledModel);
GetUnitOfWorkByCompiledModel<ICustomUnitOfWork>(compiledModel);
Payload = new DbUnitOfWork(_context, _dbRepository, _mapper, _entityMapper);
Payload = new DbUnitOfWork() {
context = _context,
dbRepoitory = _dbRepository,
mapper = _mapper,
entityMapper = _entityMapper
};
public interface IUnitOfWork
{
Foo Foo { get; set; }
}
private BaseResult<TUnitOfWork> GetUnitOfWorkByCompiledModel<TUnitOfWork>(DbCompiledModel compiledModel) where TUnitOfWork : IUnitOfWork, new()
{
return new BaseResult<TUnitOfWork>
{
Payload = new TUnitOfWork()
{
Foo = myFoo
};
};
}
services.AddTransient<IUnitOfWork, MyUnitOfWork>();
services.AddTransient<ICustomUnitOfWork, MyCustomUnitOfWork>();
public class Example
{
public Example(ICustomUnitOfWork uow)
{
}
}
private BaseResult<TUnitOfWork> GetUnitOfWorkByCompiledModel<TUnitOfWork>(DbCompiledModel compiledModel) where TUnitOfWork : IUnitOfWork, new()
{
var uow = myServiceLocator.Get<TUnitOfWork>();
uow.Foo = myFoo;
return new BaseResult<TUnitOfWork>
{
Payload = uow;
};
}