嵌套 类 中的依赖注入
Dependency Injection in nested classes
我是使用依赖注入和接口的新手,我 运行 遇到了我不知道如何解决的情况。
我正在构建一个控制台应用程序,我需要在其中使用 serilog,并从 appsettings.json
获取设置
我有 3 个 .cs 文件。
Program.cs:
static void Main(string[] args)
{
Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
var builder = new ConfigurationBuilder();
BuildConfig(builder);
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Build())
.Enrich.FromLogContext()
.CreateLogger();
Log.Logger.Information("Starting Datacollection");
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
services.AddTransient<IMyClass, MyClass>();
})
.UseSerilog()
.Build();
var svcMyClass = ActivatorUtilities.CreateInstance<MyClass>(host.Services);
svcMyClass.MyMethod();
}
IMyClass.cs:
public interface IMyClass
{
void MyMethod();
}
和MyClass.cs:
public class MyClass : IMyClass
{
private readonly ILogger<MyClass> _log;
private readonly IConfiguration _config;
public MyClass(ILogger<MyClass> log, IConfiguration config)
{
_log = log;
_config = config;
}
public void MyMethod()
{
//Do something
}
}
所有这一切都很棒。我可以使用 _log 和 _config 从 MyClass.
中访问 Serilog 和配置
但是现在需要从 MyMethod[=42= 中的新 Class (MyClass2) 调用方法], MyClass2 中的方法需要能够使用 Serilog 和配置文件。
最好的方法是什么?
这仍然取决于您如何实施解决方案。
- 如果您计划实现 IMyClass2 接口并且 MyClass2 实现了它。此外,此 IMyClass2 正在服务集合中注册。
public interface IMyClass2
{
void Test();
}
public class MyClass2 : IMyClass2
{
private readonly ILogger<MyClass> _log;
private readonly IConfiguration _config;
public MyClass2(ILogger<MyClass> log, IConfiguration config)
{
_log = log;
_config = config;
}
public void Test() {}
}
现在在 MyClass 中,您可以将 IMyClass2 作为对 MyClass 的依赖项注入,MyClass2 将处理其对记录器和配置的依赖项。
在我看来这是个好方法,因为您不必担心 MyClass2 依赖性。
- 另一件事是,如果你不想做依赖的方式,那么你可以直接创建 MyClass2 的实例并传递依赖,但在这种情况下,你必须在方法调用中传递或需要使用 ActivatorUtilities。
注意:这完全是我的意见,可能会有所不同。
您将 MyClass2 注入 MyClass 以获得对 MyClass2 方法的访问权限。
要访问 MyClass2 中的 Serilog 和配置文件,您必须 将它们单独注入 到那个 class 中,然后允许 MyClass2 方法利用它们.
总而言之,仅仅因为您将 MyClass2 注入了一个 class 并注入了 Serilog(或任何其他依赖项),并不意味着 MyClass2 也可以使用这些依赖项。
需要单独注射。
public interface IMyClass2
{
void Process();
}
public class MyClass2 : IMyClass2
{
private readonly ILogger<MyClass> _log;
private readonly IConfiguration _config;
public MyClass(ILogger<MyClass> log, IConfiguration config)
{
_log = log;
_config = config;
}
public void Process()
{
...
}
}
public class MyClass : IMyClass
{
...
private readonly IMyClass2 _myClass2;
public MyClass(..., IMyClass2 myClass2)
{
...
_myClass2 = myClass2
}
public void MyMethod()
{
var result = _myClass2.Process();
}
}
我认为您必须将 class 添加到 asp.net 服务,然后注入它而不是创建它的实例。第一步,如果您使用的是旧版本的 dotnet,请打开您的 Startup.cs 文件并添加:
builder.Services.AddScoped<IMyClass, MyClass>();
如果您使用的是较新版本,则应在 Program.cs 中添加此服务(启动和程序 classes 在新版本的 dotnet 中合并)
之后你什么时候
public class Class
{
private readonly IMyClass _class;
public Class(IMyClass myClass)
{
_class = myClass;
}
}
您可以像这样在任何地方调用您的方法:_class.MyMethod();
我是使用依赖注入和接口的新手,我 运行 遇到了我不知道如何解决的情况。
我正在构建一个控制台应用程序,我需要在其中使用 serilog,并从 appsettings.json
获取设置我有 3 个 .cs 文件。
Program.cs:
static void Main(string[] args)
{
Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
var builder = new ConfigurationBuilder();
BuildConfig(builder);
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Build())
.Enrich.FromLogContext()
.CreateLogger();
Log.Logger.Information("Starting Datacollection");
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
services.AddTransient<IMyClass, MyClass>();
})
.UseSerilog()
.Build();
var svcMyClass = ActivatorUtilities.CreateInstance<MyClass>(host.Services);
svcMyClass.MyMethod();
}
IMyClass.cs:
public interface IMyClass
{
void MyMethod();
}
和MyClass.cs:
public class MyClass : IMyClass
{
private readonly ILogger<MyClass> _log;
private readonly IConfiguration _config;
public MyClass(ILogger<MyClass> log, IConfiguration config)
{
_log = log;
_config = config;
}
public void MyMethod()
{
//Do something
}
}
所有这一切都很棒。我可以使用 _log 和 _config 从 MyClass.
中访问 Serilog 和配置但是现在需要从 MyMethod[=42= 中的新 Class (MyClass2) 调用方法], MyClass2 中的方法需要能够使用 Serilog 和配置文件。
最好的方法是什么?
这仍然取决于您如何实施解决方案。
- 如果您计划实现 IMyClass2 接口并且 MyClass2 实现了它。此外,此 IMyClass2 正在服务集合中注册。
public interface IMyClass2
{
void Test();
}
public class MyClass2 : IMyClass2
{
private readonly ILogger<MyClass> _log;
private readonly IConfiguration _config;
public MyClass2(ILogger<MyClass> log, IConfiguration config)
{
_log = log;
_config = config;
}
public void Test() {}
}
现在在 MyClass 中,您可以将 IMyClass2 作为对 MyClass 的依赖项注入,MyClass2 将处理其对记录器和配置的依赖项。
在我看来这是个好方法,因为您不必担心 MyClass2 依赖性。
- 另一件事是,如果你不想做依赖的方式,那么你可以直接创建 MyClass2 的实例并传递依赖,但在这种情况下,你必须在方法调用中传递或需要使用 ActivatorUtilities。
注意:这完全是我的意见,可能会有所不同。
您将 MyClass2 注入 MyClass 以获得对 MyClass2 方法的访问权限。
要访问 MyClass2 中的 Serilog 和配置文件,您必须 将它们单独注入 到那个 class 中,然后允许 MyClass2 方法利用它们.
总而言之,仅仅因为您将 MyClass2 注入了一个 class 并注入了 Serilog(或任何其他依赖项),并不意味着 MyClass2 也可以使用这些依赖项。
需要单独注射。
public interface IMyClass2
{
void Process();
}
public class MyClass2 : IMyClass2
{
private readonly ILogger<MyClass> _log;
private readonly IConfiguration _config;
public MyClass(ILogger<MyClass> log, IConfiguration config)
{
_log = log;
_config = config;
}
public void Process()
{
...
}
}
public class MyClass : IMyClass
{
...
private readonly IMyClass2 _myClass2;
public MyClass(..., IMyClass2 myClass2)
{
...
_myClass2 = myClass2
}
public void MyMethod()
{
var result = _myClass2.Process();
}
}
我认为您必须将 class 添加到 asp.net 服务,然后注入它而不是创建它的实例。第一步,如果您使用的是旧版本的 dotnet,请打开您的 Startup.cs 文件并添加:
builder.Services.AddScoped<IMyClass, MyClass>();
如果您使用的是较新版本,则应在 Program.cs 中添加此服务(启动和程序 classes 在新版本的 dotnet 中合并)
之后你什么时候
public class Class
{
private readonly IMyClass _class;
public Class(IMyClass myClass)
{
_class = myClass;
}
}
您可以像这样在任何地方调用您的方法:_class.MyMethod();