我创建了一个ASP.NET Core MVC/WebApi站点,该站点有一个RabbitMQ订阅者,基于James Still的博客文章Real-World PubSub Messaging with RabbitMQ.
在他的文章中,他使用静态类来启动队列订阅者并为排队事件定义事件处理程序.然后,此静态方法通过静态工厂类实例化事件处理程序类.
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
namespace NST.Web.MessageProcessing
{
public static class MessageListener
{
private static IConnection _connection;
private static IModel _channel;
public static void Start(string hostName, string userName, string password, int port)
{
var factory = new ConnectionFactory
{
HostName = hostName,
Port = port,
UserName = userName,
Password = password,
VirtualHost = "/",
AutomaticRecoveryEnabled = true,
NetworkRecoveryInterval = TimeSpan.FromSeconds(15)
};
_connection = factory.CreateConnection();
_channel = …Run Code Online (Sandbox Code Playgroud) c# dependency-injection rabbitmq service-locator asp.net-core
我如何为特定类注入不同的对象实现?
例如,在统一中我可以:定义两个实现 IRepository
container.RegisterType<IRepository, TestSuiteRepositor("TestSuiteRepository");
container.RegisterType<IRepository, BaseRepository>();
Run Code Online (Sandbox Code Playgroud)
并致电所需的实施
public BaselineManager([Dependency("TestSuiteRepository")]IRepository repository)
Run Code Online (Sandbox Code Playgroud) 在ASP.NET Core 2中,我们可以像这样添加Azure Redis缓存:
services.AddDistributedRedisCache(config =>
{
config.Configuration = Configuration.GetConnectionString("RedisCacheConnection");
config.InstanceName = "MYINSTANCE";
});
Run Code Online (Sandbox Code Playgroud)
那么用法将是这样的:
private readonly IDistributedCache _cache;
public MyController(IDistributedCache cache)
{
_cache = cache;
}
Run Code Online (Sandbox Code Playgroud)
我该怎么办才能拥有:
private readonly IDistributedCache _cache1;
private readonly IDistributedCache _cache2;
public MyController(IDistributedCache cache1, IDistributedCache cache2)
{
_cache1 = cache1;
_cache2 = cache2;
}
Run Code Online (Sandbox Code Playgroud)
我的问题如何添加另一个指向不同的Azure Redis缓存连接和实例的服务,并在我想使用它们时将它们分开?
我正在开展一个侧面项目,以更好地理解控制和依赖注入的反转以及不同的设计模式.
我想知道在工厂和战略模式中使用DI是否有最佳实践?
我的挑战来自于一个策略(从工厂构建)需要为每个可能的构造函数和实现提供不同的参数.结果,我发现自己在服务入口点声明了所有可能的接口,并将它们传递给应用程序.因此,必须针对新的和各种策略类实现更改入口点.
为了便于说明,我在下面汇总了一个配对示例.我的这个项目的堆栈是.NET 4.5/C#和Unity for IoC/DI.
在此示例应用程序中,我添加了一个默认的Program类,负责接受虚构的订单,并根据订单属性和所选的送货提供商计算运费.UPS,DHL和Fedex有不同的计算方法,每个实现可能依赖或不依赖于其他服务(访问数据库,api等).
public class Order
{
public string ShippingMethod { get; set; }
public int OrderTotal { get; set; }
public int OrderWeight { get; set; }
public int OrderZipCode { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
用于计算运费的虚拟计划或服务
public class Program
{
// register the interfaces with DI container in a separate config class (Unity in this case)
private readonly IShippingStrategyFactory _shippingStrategyFactory;
public Program(IShippingStrategyFactory shippingStrategyFactory)
{
_shippingStrategyFactory = shippingStrategyFactory;
}
public …Run Code Online (Sandbox Code Playgroud) c# design-patterns dependency-injection strategy-pattern factory-pattern
我有一个BlobStorageRepository类用于与 Azure blob 存储交互。它实现一个接口IBlobStorageRepository。
我需要使用两个实例,BlobStorageRepository但它们使用不同的凭据进行设置:
在我的Startup.cs:
// Normal storage
var storageCredentials = new StorageCredentials(_appSettings.BlobStorageAccountName, _appSettings.BlobStorageAccountKey);
var cloudBlobStorageAccount = new CloudStorageAccount(storageCredentials, true);
var cloudBlobClient = cloudBlobStorageAccount.CreateCloudBlobClient();
var blobRepository = new BlobStorageRepository(cloudBlobClient);
// Quarantine storage
var quarantineStorageCredentials = new StorageCredentials(_appSettings.QuarantineBlobStorageAccountName, _appSettings.QuarantineBlobStorageAccountKey);
var quarantineCloudBlobStorageAccount = new CloudStorageAccount(quarantineStorageCredentials, true);
var quarantineCloudBlobClient = quarantineCloudBlobStorageAccount.CreateCloudBlobClient();
var quarantineBlobRepository = new BlobStorageRepository(quarantineCloudBlobClient);
services.AddSingleton<IBlobStorageRepository>(blobRepository);
services.AddSingleton<IBlobStorageRepository>(quarantineBlobRepository);
Run Code Online (Sandbox Code Playgroud)
如何配置上述内容,以便可以解析类中的依赖项并获取两个不同的实例,即:
private readonly IBlobStorageRepository _blobStorageRepository;
private readonly IBlobStorageRepository _quarantineBlobStorageRepository;
public DocumentService(IBlobStorageRepository blobStorageRepository, IBlobStorageRepository quarantineBlobStorageRepository)
{
_blobStorageRepository …Run Code Online (Sandbox Code Playgroud) 我正在努力使用, &NpgsqlConnection()中的多个连接字符串注册 DI 。ASP.NET Core 3.1Dapper v2.0.78Postgres v11
我将提供当前状态并修复以下代码:
步骤1。Startup.cs --> ConfigureServices()
services.AddTransient<IDbConnectionFactory, DapperDbConnectionFactory>(sp =>
{
var connectionDict = new Dictionary<DatabaseConnectionName, string>
{
{ DatabaseConnectionName.Cnn1, "Connectionstring 1"},
{ DatabaseConnectionName.Cnn2, "Connectionstring 2"}
};
return new DapperDbConnectionFactory(connectionDict);
});
Run Code Online (Sandbox Code Playgroud)
第2步。DapperDbConnectionFactory看起来像这样:
public class DapperDbConnectionFactory : IDbConnectionFactory
{
private readonly IDictionary<DatabaseConnectionName, string> _connectionDict;
public DapperDbConnectionFactory(IDictionary<DatabaseConnectionName, string> connectionDict)
{
_connectionDict = connectionDict;
}
public IDbConnection CreateDbConnection(DatabaseConnectionName connectionName)
{
string connectionString = null;
if …Run Code Online (Sandbox Code Playgroud) c# postgresql dependency-injection connection-pooling asp.net-core
我在简单的 ASP.NET Core Web API 中创建,假设我有一个如下界面:
public interface ITestService
{
string GetDate();
}
Run Code Online (Sandbox Code Playgroud)
我使用 Autofac 来处理 DI,对于上述接口,我有两个注册类型(TestService 和 TestComponent 实现 ITestService):
builder.RegisterType<TestService>().As<ITestService>().Keyed<ITestService>("service");
builder.RegisterType<TestComponent>().As<ITestService>().Keyed<ITestService>("component");
Run Code Online (Sandbox Code Playgroud)
我知道我可以注册我的类型来使用这些绑定中的任何一个,并且我知道有一种方法可以获得正确的类型,如此处讨论的:
var services = serviceProvider.GetServices<ITestService>();
var testComponent= services.First(o => o.GetType() == typeof(TestComponent));
Run Code Online (Sandbox Code Playgroud)
由于我使用 Autofac 并使用 Keyed Services 注册了我的类型,因此如何使用 IServiceProvider 和我在绑定中提供的密钥(“服务”或“组件”)解析正确的 ITestService?
我正在尝试使用IHostedService创建后台服务.如果我只有一个后台服务,一切正常.当我尝试创建多个实现时,IHostedService只有第一个实际运行的实现.
services.AddSingleton<IHostedService, HostedServiceOne>();
services.AddSingleton<IHostedService, HostedServiceTwo>();
Run Code Online (Sandbox Code Playgroud)
在上面的例子StartAsync上HostedServiceOne被调用,但StartAsync上HostedServiceTwo不会被调用.如果我换登记的两种实现方式的顺序IHostedService(把IHostedServiceTwo前IHostedServiceOne),然后StartAsync在HostedServiceTwo被调用而从来不是HostedServiceOne.
编辑:
我被引导到以下内容:
然而,这不适合IHostedService.要使用建议的方法,我将不得不打电话,serviceProvider.GetServices<IService>();但似乎IHostedService.StartAsync似乎在内部调用.我甚至不确定我会在哪里触发它IHostedService.StartAsync.
我对 .NET Core 中的依赖注入感到困惑,其中我有许多相互耦合的依赖项。我有一个MyClass实现接口的类IMyClass,如下所示:
public class MyClass : IMyClass
{
private IClass classA;
private IClass classB;
public MyClass (ClassA classA, ClassB classB)
{
this.classA = classA;
this.classB = classB;
}
....
}
Run Code Online (Sandbox Code Playgroud)
类ClassA和ClassB接口的实现IClass如下:
public class ClassA : IClass
{
public ClassA (many other DI)
{
}
}
public class ClassB : IClass
{
private IClass baseClass;
public ClassB (IClass baseClass, ...)
{
this.baseClass = baseClass;
....
}
}
Run Code Online (Sandbox Code Playgroud)
在我的启动文件中,我应该如何注册我的依赖项。我已尝试以下方法,但不起作用:
services.AddSingleton<ClassA>(); …Run Code Online (Sandbox Code Playgroud) 就在最近,我一直在尝试新的asp.net功能并遇到了这个问题。我知道我们可以将配置读取为强类型实例。但是我不知道如何在Microsoft依赖项注入中将配置注入到类中。
public interface IProvider
{
IMyConfiguration Configuration {get;}
Task Connect();
}
public abstract class Provider: IProvider
{
private IMyConfiguration _myConfig;
public Provider(IMyConfiguration config)
{
this._myConfig= config;
}
public IMyConfiguration Configuration => _myConfig;
public abstract Task Connect();
}
public class ProviderOne:Provider
{
public ProviderOne(IMyConfiguration config) : base(config)
{
}
public Task Connect()
{
//implementation
}
}
Run Code Online (Sandbox Code Playgroud)
配置类:
public interface IMyConfiguration
{
string TerminalId { get;set; }
bool IsDefault {get;set;}
}
public class MyConfiguration : IMyConfiguration
{
string TerminalId { get;set; } …Run Code Online (Sandbox Code Playgroud) Unity、Autofac 以及可能还有相当多的其他依赖注入包都支持“键控依赖注入容器”,允许注册接口的多个实现并通过键(无论是字符串、整数、枚举还是其他任何形式)唯一地标识它们)。
然而,到目前为止我至少可以看到,.NET Core 没有这样的功能,如果我要尝试实现这样的功能,我必须采取解决方法或找到一些 hacky 解决方案。我想知道,是否有特殊原因没有在 .NET Core 中引入?
统一示例:
container.RegisterType<IService, ServiceImplementation1>("1");
container.RegisterType<IService, ServiceImplementation2>("2");
Run Code Online (Sandbox Code Playgroud)
Autofac 示例:
builder.RegisterType<ServiceImplementation1>().Keyed<IService>("1");
builder.RegisterType<ServiceImplementation2>().Keyed<IService>("2");
Run Code Online (Sandbox Code Playgroud)