在 class 的每个方法中提供一个新的对象实例?
Provide a new object instance in every method of a class?
假设我想在 class 中调用方法时使用新的 DbContext 对象,但不通过参数获取它。像这样
class MyClass {
public virtual void MethodOne() {
// Having automatically a new instance of DbContext
}
public virtual void MethodTwo() {
// Also having automatically a new instance of DbContext
}
}
我真正希望的是一种实现此目的的 DI 方式。喜欢 public void Method(IMyWayOfContext context)
.
class MyClass {
public virtual void MethodOne(IMyWayOfContext context)) {
}
public virtual void MethodTwo(IMyWayOfContext context) {
}
}
从这个 class 继承的其他 classes 必须提供新的 dbcontext 实例。这就是为什么我不想在函数内部创建一个新实例
制作一个只有 getter 的 属性 每次都会 return 新实例
protected DbContext MyDBContext
{
get
{
return new DbContext();
}
}
编辑:如果你想要某种依赖注入,你可以使你的class通用并传递给class你想要什么类型的上下文的实例
class MyClass<T> {
protected DbContext MyDBContext
{
get
{
return Activator.CreateInstance<T>();
}
}
public void MethodOne() {
// Having automatically a new instance of DbContext
}
public void MethodTwo() {
// Also having automatically a new instance of DbContext
}
}
您可以这样做(通用接口,加上具有多个约束的包装器):
class DBContext{ }
interface IDoesMethods<TContext> where TContext : new()
{
void MethodOne(TContext context = default(TContext));
void MethodTwo(TContext context = default(TContext));
}
class MyClass : IDoesMethods<DBContext>
{
public void MethodOne(DBContext context)
{
}
public void MethodTwo(DBContext context)
{
}
}
class MyContextWrapper<TClass, TContext> : IDoesMethods<TContext> where TContext : new() where TClass : IDoesMethods<TContext>, new()
{
public void MethodOne(TContext context = default(TContext))
{
instance.MethodOne(new TContext());
}
public void MethodTwo(TContext context = default(TContext))
{
instance.MethodTwo(new TContext());
}
private TClass instance = new TClass();
}
class Program
{
static void Main(string[] args)
{
var wrapper = new MyContextWrapper<MyClass, DBContext>();
wrapper.MethodOne();
wrapper.MethodTwo();
}
}
您的简单解决方案可以这样工作:
class MyClass {
protected DbContext InternalContext {
return new DbContext();
}
public virtual void MethodOne(DbContext dc = null) {
if(dc == null)
dc = InternalContext;
// do your work
}
public virtual void MethodTwo(DbContext dc = nnull) {
if(dc == null)
dc = InternalContext;
// do your work
}
}
在这种情况下,您必须注意处理 InternalContext
虽然这里的答案看起来有效,但它们似乎并不能完全满足您拥有依赖 DI 的解决方案的要求。
最简单的 DI 大部分时间都是通过构造函数注入实现的。
您的设计已经很好,DI 就绪。
确实,通过构造函数请求依赖关系很好。
您需要在应用程序的组合根中决定需要传递的实现。
使用 DI 库会有帮助(但它不是启用 DI 所必需的)。
根据您的实际 class 设计:
class MyClass {
public virtual void MethodOne(IMyWayOfContextFactory contextFactory)) {
using(var context = contextFactory.Create()){
//play with context
}
}
public virtual void MethodTwo(IMyWayOfContextFactory contextFactory) {
using(var context = contextFactory.Create()){
//play with context
}
}
}
public ContextFactory : IMyWayOfContextFactory {
IMyWayOfContext Create(){
return new MyWayOfContext();
}
}
没有工厂和像 SimpleInjector 这样的 DI 容器,你可以:
class MyClass {
public virtual void MethodOne(IMyWayOfContext context)) {
//play with context
}
public virtual void MethodTwo(IMyWayOfContext context) {
//play with context
}
}
并使用可配置的生活方式管理在组合根目录中注册您的组件一次:
container.Register<IMyWayOfContext, MyWayOfContext>(Lifestyle.Transient);
如果您想配置何时注入上下文实例,后一种方法更简单。事实上,这样的配置是内置在 DI 容器库中的。例如,参见:Lifestyle of component with SimpleInjector
假设我想在 class 中调用方法时使用新的 DbContext 对象,但不通过参数获取它。像这样
class MyClass {
public virtual void MethodOne() {
// Having automatically a new instance of DbContext
}
public virtual void MethodTwo() {
// Also having automatically a new instance of DbContext
}
}
我真正希望的是一种实现此目的的 DI 方式。喜欢 public void Method(IMyWayOfContext context)
.
class MyClass {
public virtual void MethodOne(IMyWayOfContext context)) {
}
public virtual void MethodTwo(IMyWayOfContext context) {
}
}
从这个 class 继承的其他 classes 必须提供新的 dbcontext 实例。这就是为什么我不想在函数内部创建一个新实例
制作一个只有 getter 的 属性 每次都会 return 新实例
protected DbContext MyDBContext
{
get
{
return new DbContext();
}
}
编辑:如果你想要某种依赖注入,你可以使你的class通用并传递给class你想要什么类型的上下文的实例
class MyClass<T> {
protected DbContext MyDBContext
{
get
{
return Activator.CreateInstance<T>();
}
}
public void MethodOne() {
// Having automatically a new instance of DbContext
}
public void MethodTwo() {
// Also having automatically a new instance of DbContext
}
}
您可以这样做(通用接口,加上具有多个约束的包装器):
class DBContext{ }
interface IDoesMethods<TContext> where TContext : new()
{
void MethodOne(TContext context = default(TContext));
void MethodTwo(TContext context = default(TContext));
}
class MyClass : IDoesMethods<DBContext>
{
public void MethodOne(DBContext context)
{
}
public void MethodTwo(DBContext context)
{
}
}
class MyContextWrapper<TClass, TContext> : IDoesMethods<TContext> where TContext : new() where TClass : IDoesMethods<TContext>, new()
{
public void MethodOne(TContext context = default(TContext))
{
instance.MethodOne(new TContext());
}
public void MethodTwo(TContext context = default(TContext))
{
instance.MethodTwo(new TContext());
}
private TClass instance = new TClass();
}
class Program
{
static void Main(string[] args)
{
var wrapper = new MyContextWrapper<MyClass, DBContext>();
wrapper.MethodOne();
wrapper.MethodTwo();
}
}
您的简单解决方案可以这样工作:
class MyClass {
protected DbContext InternalContext {
return new DbContext();
}
public virtual void MethodOne(DbContext dc = null) {
if(dc == null)
dc = InternalContext;
// do your work
}
public virtual void MethodTwo(DbContext dc = nnull) {
if(dc == null)
dc = InternalContext;
// do your work
}
}
在这种情况下,您必须注意处理 InternalContext
虽然这里的答案看起来有效,但它们似乎并不能完全满足您拥有依赖 DI 的解决方案的要求。
最简单的 DI 大部分时间都是通过构造函数注入实现的。
您的设计已经很好,DI 就绪。 确实,通过构造函数请求依赖关系很好。 您需要在应用程序的组合根中决定需要传递的实现。
使用 DI 库会有帮助(但它不是启用 DI 所必需的)。
根据您的实际 class 设计:
class MyClass {
public virtual void MethodOne(IMyWayOfContextFactory contextFactory)) {
using(var context = contextFactory.Create()){
//play with context
}
}
public virtual void MethodTwo(IMyWayOfContextFactory contextFactory) {
using(var context = contextFactory.Create()){
//play with context
}
}
}
public ContextFactory : IMyWayOfContextFactory {
IMyWayOfContext Create(){
return new MyWayOfContext();
}
}
没有工厂和像 SimpleInjector 这样的 DI 容器,你可以:
class MyClass {
public virtual void MethodOne(IMyWayOfContext context)) {
//play with context
}
public virtual void MethodTwo(IMyWayOfContext context) {
//play with context
}
}
并使用可配置的生活方式管理在组合根目录中注册您的组件一次:
container.Register<IMyWayOfContext, MyWayOfContext>(Lifestyle.Transient);
如果您想配置何时注入上下文实例,后一种方法更简单。事实上,这样的配置是内置在 DI 容器库中的。例如,参见:Lifestyle of component with SimpleInjector