摘要 类 和依赖注入
Abstract Classes and Dependency Injection
我想了解如何实现依赖注入,但我有一些问题:
我可以使用摘要 classes 吗?我读了一些关于 DI 的文章,如果我理解得很好,他们说你必须使用接口而不是抽象 classes - 我怎样才能避免在不同的 classes 中使用重复的代码?
如果我在 class 中有很多依赖项,我是否必须将它们全部注入到构造函数中?如果我不在所有方法中都使用它们怎么办?
我可以实例对象吗?如果我不实例化对象,我怎么能调用 class?
的构造函数
简答:
- DI 只是一个允许在 class 之外创建依赖的模式。因此,据我所知,您可以使用抽象 class,具体取决于您如何导入容器。
- 您可以
inject
通过其他方法。 (构造函数在很多方面只是其中之一)。
- 您应该使用 lib 或 imp 您的容器。通常,他们使用
decorator
来保存有关依赖项的描述,然后您使用它来创建实例。
摘要类
1- Can i use abstract classes? I read some articles about DI and, if i understanded well, they say that u have to use interface but not abstract classes but how can i avoid to use duplicated code in diferent classes?
我认为你在谈论两件不同的事情。
一个。您可以使用抽象 类 而不必使用接口。这是一个例子。
internal abstract class BaseService
{
public abstract string GetString();
}
internal class ServiceC : BaseService
{
public override string GetString() => "ServiceB";
}
internal class ServiceD
{
public ServiceD(BaseService baseService) { BaseService = baseService; }
public BaseService BaseService { get; }
}
static void Main(string[] args)
{
// ServiceCollection is package Microsoft.Extensions.DependencyInjection
var serviceProvider = new ServiceCollection()
.AddSingleton<BaseService, ServiceC>()
.AddSingleton<ServiceD>()
.BuildServiceProvider();
var serviceC = serviceProvider.GetService<BaseService>();
var serviceD = serviceProvider.GetService<ServiceD>();
//serviceD.BaseService is ServiceC
乙。即使你使用接口,你仍然可以使用抽象 类,对于非 DI 部分。
请考虑以下示例。
internal abstract class BaseService { protected string GetCommon() => "Common functionality"; }
internal interface IServiceA { string GetA(); }
internal interface IServiceB { string GetB(); }
internal class ServiceA : BaseService, IServiceA
{
public string GetA() => "A + " + GetCommon();
}
internal class ServiceB : BaseService, IServiceB
{
public string GetB() => "B + " + GetCommon();
}
static void Main(string[] args)
{
// ServiceCollection is package Microsoft.Extensions.DependencyInjection
var serviceProvider = new ServiceCollection()
.AddSingleton<IServiceA, ServiceA>()
.AddSingleton<IServiceB, ServiceB>()
.BuildServiceProvider();
var serviceA = serviceProvider.GetService<IServiceA>();
Console.WriteLine(serviceA.GetA()); // "A + Common functionality"
Console.WriteLine(serviceProvider.GetService<IServiceB>().GetB()); // B + Common functionality
}
只有构造函数?
您可以在方法中使用额外的依赖项。
internal class ServiceE
{
private readonly IServiceA a;
public ServiceE(IServiceA a)
{
this.a = a;
}
public string AandB(IServiceB b) => a.GetA() + b.GetB();
}
Can I use abstract classes?
是的。然而,在实践中,使用接口可能有一些优势。例如,在测试时,有时模拟接口比抽象 classes 更容易。我还要问为什么你觉得有必要使用抽象 classes 而不是接口,但这会导致下一点......
How can I avoid using duplicated code in different classes?
一般来说,为了代码重用,您应该favor composition over inheritence。
If I have many dependencies in a class, do I have to inject all of them in the constructor?
不,还有其他方法可以注入依赖项,例如方法。但我会说构造函数注入是“classic”DI 模式,它有一些优点。例如,如果您在构造函数中注入所有依赖项,则无需担心有人在设置所需的依赖项之前调用您的方法 class。
What if I don't use all of them in all methods?
小范围内没问题。但是,如果您有很多依赖项或很多方法,这可能表明您的 class 做得太多了。如果您有不同的 methods/dependencies 组(例如,如果方法 A、B、C 使用依赖项 1、2,方法 D、E、F 使用依赖项 3、4),则尤其如此。参见 Single Responsibility Principle。
Can I instance objects? If I don't instance objects, how could I invoke the constructor of a class?
考虑不同类型的 class 很重要。对于仅保存数据的简单 POCO classes,您不需要使用 DI——根据需要随意 new
它们。然而,DI 对于执行某些业务逻辑或与某些外部系统(如数据库)交互的服务类型 classes 非常重要。在那种情况下,您应该 而不是 使用 new
在您的 classes 中实例化它们。
当然,您有时必须实例化这些对象。但是 DI 的要点是依赖于 X 的 class 不应该也实例化 X。依赖注入框架通常有一个“组合根”,所有的依赖都在这里连接起来。在那里您会看到正在创建的新实例。
我想了解如何实现依赖注入,但我有一些问题:
我可以使用摘要 classes 吗?我读了一些关于 DI 的文章,如果我理解得很好,他们说你必须使用接口而不是抽象 classes - 我怎样才能避免在不同的 classes 中使用重复的代码?
如果我在 class 中有很多依赖项,我是否必须将它们全部注入到构造函数中?如果我不在所有方法中都使用它们怎么办?
我可以实例对象吗?如果我不实例化对象,我怎么能调用 class?
的构造函数
简答:
- DI 只是一个允许在 class 之外创建依赖的模式。因此,据我所知,您可以使用抽象 class,具体取决于您如何导入容器。
- 您可以
inject
通过其他方法。 (构造函数在很多方面只是其中之一)。 - 您应该使用 lib 或 imp 您的容器。通常,他们使用
decorator
来保存有关依赖项的描述,然后您使用它来创建实例。
摘要类
1- Can i use abstract classes? I read some articles about DI and, if i understanded well, they say that u have to use interface but not abstract classes but how can i avoid to use duplicated code in diferent classes?
我认为你在谈论两件不同的事情。
一个。您可以使用抽象 类 而不必使用接口。这是一个例子。
internal abstract class BaseService
{
public abstract string GetString();
}
internal class ServiceC : BaseService
{
public override string GetString() => "ServiceB";
}
internal class ServiceD
{
public ServiceD(BaseService baseService) { BaseService = baseService; }
public BaseService BaseService { get; }
}
static void Main(string[] args)
{
// ServiceCollection is package Microsoft.Extensions.DependencyInjection
var serviceProvider = new ServiceCollection()
.AddSingleton<BaseService, ServiceC>()
.AddSingleton<ServiceD>()
.BuildServiceProvider();
var serviceC = serviceProvider.GetService<BaseService>();
var serviceD = serviceProvider.GetService<ServiceD>();
//serviceD.BaseService is ServiceC
乙。即使你使用接口,你仍然可以使用抽象 类,对于非 DI 部分。
请考虑以下示例。
internal abstract class BaseService { protected string GetCommon() => "Common functionality"; }
internal interface IServiceA { string GetA(); }
internal interface IServiceB { string GetB(); }
internal class ServiceA : BaseService, IServiceA
{
public string GetA() => "A + " + GetCommon();
}
internal class ServiceB : BaseService, IServiceB
{
public string GetB() => "B + " + GetCommon();
}
static void Main(string[] args)
{
// ServiceCollection is package Microsoft.Extensions.DependencyInjection
var serviceProvider = new ServiceCollection()
.AddSingleton<IServiceA, ServiceA>()
.AddSingleton<IServiceB, ServiceB>()
.BuildServiceProvider();
var serviceA = serviceProvider.GetService<IServiceA>();
Console.WriteLine(serviceA.GetA()); // "A + Common functionality"
Console.WriteLine(serviceProvider.GetService<IServiceB>().GetB()); // B + Common functionality
}
只有构造函数?
您可以在方法中使用额外的依赖项。
internal class ServiceE
{
private readonly IServiceA a;
public ServiceE(IServiceA a)
{
this.a = a;
}
public string AandB(IServiceB b) => a.GetA() + b.GetB();
}
Can I use abstract classes?
是的。然而,在实践中,使用接口可能有一些优势。例如,在测试时,有时模拟接口比抽象 classes 更容易。我还要问为什么你觉得有必要使用抽象 classes 而不是接口,但这会导致下一点......
How can I avoid using duplicated code in different classes?
一般来说,为了代码重用,您应该favor composition over inheritence。
If I have many dependencies in a class, do I have to inject all of them in the constructor?
不,还有其他方法可以注入依赖项,例如方法。但我会说构造函数注入是“classic”DI 模式,它有一些优点。例如,如果您在构造函数中注入所有依赖项,则无需担心有人在设置所需的依赖项之前调用您的方法 class。
What if I don't use all of them in all methods?
小范围内没问题。但是,如果您有很多依赖项或很多方法,这可能表明您的 class 做得太多了。如果您有不同的 methods/dependencies 组(例如,如果方法 A、B、C 使用依赖项 1、2,方法 D、E、F 使用依赖项 3、4),则尤其如此。参见 Single Responsibility Principle。
Can I instance objects? If I don't instance objects, how could I invoke the constructor of a class?
考虑不同类型的 class 很重要。对于仅保存数据的简单 POCO classes,您不需要使用 DI——根据需要随意 new
它们。然而,DI 对于执行某些业务逻辑或与某些外部系统(如数据库)交互的服务类型 classes 非常重要。在那种情况下,您应该 而不是 使用 new
在您的 classes 中实例化它们。
当然,您有时必须实例化这些对象。但是 DI 的要点是依赖于 X 的 class 不应该也实例化 X。依赖注入框架通常有一个“组合根”,所有的依赖都在这里连接起来。在那里您会看到正在创建的新实例。