从它实现的接口创建 class 的实例
Create Instance of a class from interface which it implements
您好,我正在尝试构建一个通用的 UoWFactory,它创建一个 UnitOfWork(将有一个默认的工作单元和多个自定义实现)。到目前为止,我已经能够创建创建默认 UoW 和 returns 的工厂方法。我已根据传递的参数将以下方法修改为 return 指定的 UoW。
当前实施
private BaseResult<IUnitOfWork> GetUnitOfWorkByCompiledModel<IUnitOfWork>(DbCompiledModel compiledModel)
{
return new BaseResult<IUnitOfWork>
{
Payload = new DbUnitOfWork(_context, _dbRepository, _mapper, _entityMapper)
};
}
我希望有这样的东西
private BaseResult<TUoW> GetUnitOfWorkByCompiledModel<IUnitOfWork>(DbCompiledModel compiledModel) where TUoW :Class
{
return new BaseResult<TUoW>
{
//Create instance of type TUoW where TUoW can be IUnitOfWork, ICustomUnitOfWork etc
//DbUnitOfWork implements IUnitOfWork and CustomUnitOfWork implements ICustomUnitOfWork
//All the TUoW will have constructors with identical parmeters
};
}
创建 class 的实例很简单
Activator.CreateInstance (Type type, object[] args);
但是如果我将接口类型作为参数传递,如何创建 DbUnitOfWork 或 CustomUnitOfWork 的实例。
例如:-
GetUnitOfWorkByCompiledModel<IUnitOfWork>(compiledModel);
GetUnitOfWorkByCompiledModel<ICustomUnitOfWork>(compiledModel);
如果 DbUnitOfWork Class 具有正确的值名称
,这将有效
你想改变什么
Payload = new DbUnitOfWork(_context, _dbRepository, _mapper, _entityMapper);
改为
Payload = new DbUnitOfWork() {
context = _context,
dbRepoitory = _dbRepository,
mapper = _mapper,
entityMapper = _entityMapper
};
希望这项工作。
无参数构造函数
你想要的是可能的,除了一件事:你不能使用带有通用类型参数的非默认构造函数。你无法避免这一点。
这里的部分问题是您无法从接口强制执行特定的构造函数方法签名,因此无法保证 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
};
};
}
我认为这符合您的期望,而且变化很小。
解析接口
But if I pass Interface type as a parameter how to create instance of DbUnitOfWork or CustomUnitOfWork. eg
GetUnitOfWorkByCompiledModel<IUnitOfWork>(compiledModel);
GetUnitOfWorkByCompiledModel<ICustomUnitOfWork>(compiledModel);
如果您打算使用没有具体类型的接口类型,那么以上答案是不完整的。
不管泛型类型的问题,如果你想将接口解析为具体类型,你需要注册你想使用的具体类型。
这通常是通过依赖注入框架完成的。这些框架要求您注册所有必要的类型,例如.NET Core 示例:
services.AddTransient<IUnitOfWork, MyUnitOfWork>();
services.AddTransient<ICustomUnitOfWork, MyCustomUnitOfWork>();
然后框架会使用这个注册自动为你填写构造函数参数:
public class Example
{
public Example(ICustomUnitOfWork uow)
{
}
}
此处的最佳实践方法要求您将此依赖项注入贯穿整个框架,因此您永远不需要显式调用任何构造函数(而是让 DI 框架为您完成)。
可以使用service locator,它本质上是一个你可以随意调用的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 方法。
我无法在单个 Whosebug 答案的范围内详细说明依赖注入。我建议您查看依赖注入,因为它完全符合您的期望(通过引用接口获取具体类型)
您好,我正在尝试构建一个通用的 UoWFactory,它创建一个 UnitOfWork(将有一个默认的工作单元和多个自定义实现)。到目前为止,我已经能够创建创建默认 UoW 和 returns 的工厂方法。我已根据传递的参数将以下方法修改为 return 指定的 UoW。
当前实施
private BaseResult<IUnitOfWork> GetUnitOfWorkByCompiledModel<IUnitOfWork>(DbCompiledModel compiledModel)
{
return new BaseResult<IUnitOfWork>
{
Payload = new DbUnitOfWork(_context, _dbRepository, _mapper, _entityMapper)
};
}
我希望有这样的东西
private BaseResult<TUoW> GetUnitOfWorkByCompiledModel<IUnitOfWork>(DbCompiledModel compiledModel) where TUoW :Class
{
return new BaseResult<TUoW>
{
//Create instance of type TUoW where TUoW can be IUnitOfWork, ICustomUnitOfWork etc
//DbUnitOfWork implements IUnitOfWork and CustomUnitOfWork implements ICustomUnitOfWork
//All the TUoW will have constructors with identical parmeters
};
}
创建 class 的实例很简单
Activator.CreateInstance (Type type, object[] args);
但是如果我将接口类型作为参数传递,如何创建 DbUnitOfWork 或 CustomUnitOfWork 的实例。 例如:-
GetUnitOfWorkByCompiledModel<IUnitOfWork>(compiledModel);
GetUnitOfWorkByCompiledModel<ICustomUnitOfWork>(compiledModel);
如果 DbUnitOfWork Class 具有正确的值名称
,这将有效你想改变什么
Payload = new DbUnitOfWork(_context, _dbRepository, _mapper, _entityMapper);
改为
Payload = new DbUnitOfWork() {
context = _context,
dbRepoitory = _dbRepository,
mapper = _mapper,
entityMapper = _entityMapper
};
希望这项工作。
无参数构造函数
你想要的是可能的,除了一件事:你不能使用带有通用类型参数的非默认构造函数。你无法避免这一点。
这里的部分问题是您无法从接口强制执行特定的构造函数方法签名,因此无法保证 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
};
};
}
我认为这符合您的期望,而且变化很小。
解析接口
But if I pass Interface type as a parameter how to create instance of DbUnitOfWork or CustomUnitOfWork. eg
GetUnitOfWorkByCompiledModel<IUnitOfWork>(compiledModel);
GetUnitOfWorkByCompiledModel<ICustomUnitOfWork>(compiledModel);
如果您打算使用没有具体类型的接口类型,那么以上答案是不完整的。
不管泛型类型的问题,如果你想将接口解析为具体类型,你需要注册你想使用的具体类型。
这通常是通过依赖注入框架完成的。这些框架要求您注册所有必要的类型,例如.NET Core 示例:
services.AddTransient<IUnitOfWork, MyUnitOfWork>();
services.AddTransient<ICustomUnitOfWork, MyCustomUnitOfWork>();
然后框架会使用这个注册自动为你填写构造函数参数:
public class Example
{
public Example(ICustomUnitOfWork uow)
{
}
}
此处的最佳实践方法要求您将此依赖项注入贯穿整个框架,因此您永远不需要显式调用任何构造函数(而是让 DI 框架为您完成)。
可以使用service locator,它本质上是一个你可以随意调用的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 方法。
我无法在单个 Whosebug 答案的范围内详细说明依赖注入。我建议您查看依赖注入,因为它完全符合您的期望(通过引用接口获取具体类型)