C# 从类实现的接口创建类的实例

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) {

您好,我正在尝试构建一个通用UoWFactory,它创建一个unitofwork,将有一个默认unitofwork和多个自定义实现。到目前为止,我能够创建工厂方法,该方法创建默认UoW并返回它。我修改了以下方法,根据传递的参数返回指定的UoW

当前实施

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;
    };
}