注册具有相同接口但不同构造函数参数的多个单例

我有2个存储(Azure)帐户让我们调用它们src和dest我有控制器需要访问这两个,我正在尝试找出如何有条件地注册这2个单身。

这个答案给了我一些希望,但我不能完全解决,我想做的是(感谢RegisterSingletonConditional不是一个有效的fn):

IBlobAccessClient src = new BlobAccessClient(srcConnectionString); IBlobAccessClient dest = new BlobAccessClient(destConnectionString); container.RegisterSingletonConditional( src, c => c.Consumer.Target.Parameter.Name.Contains("src")); container.RegisterSingletonConditional( dest, c => c.Consumer.Target.Parameter.Name.Contains("dest")); 

任何指导赞赏。

有一个非通用的RegisterConditional重载,它接受一个Registration对象。 您可以将BlobAccessClient实例包装在Registration并将其传递给RegisterConditional ,如下所示:

 container.RegisterConditional(typeof(IBlobAccessClient), Lifestyle.Singleton.CreateRegistration( () => new BlobAccessClient(srcConnectionString), container), c => c.Consumer.Target.Parameter.Name.Contains("src")); container.RegisterConditional(typeof(IBlobAccessClient), Lifestyle.Singleton.CreateRegistration( () => new BlobAccessClient(destConnectionString), container), c => c.Consumer.Target.Parameter.Name.Contains("dest")); 

如果这是一种常见模式,您可以通过定义一个简单的扩展方法来简化您的代码,如下所示:

 public static void RegisterConditionalInstance( this Container container, TService instance, Predicate predicate) where TService : class { container.RegisterConditional(typeof(TService), Lifestyle.Singleton.CreateRegistration(() => instance, container), predicate); } 

这允许您将以前的配置减少到以下内容:

 container.RegisterConditionalInstance( new BlobAccessClient(srcConnectionString), c => c.Consumer.Target.Parameter.Name.Contains("src")); container.RegisterConditionalInstance( new BlobAccessClient(destConnectionString), c => c.Consumer.Target.Parameter.Name.Contains("dest")); 

或者,您也可以通过将谓词解压缩为简单方法来简化谓词:

 private static Predicate InjectedIntoTargetNamed(string targetName) => c => c.Consumer.Target.Name.Contains(targetName); 

这会将注册减少到以下内容:

 container.RegisterConditionalInstance( new BlobAccessClient(srcConnectionString), InjectedIntoTargetNamed("src")); container.RegisterConditionalInstance( new BlobAccessClient(destConnectionString), InjectedIntoTargetNamed("dest")); 

我建议定义两个新接口:

 public interface IBlobAccessClientSource : IBlobAccessClient { } public interface IBlobAccessClientDestination : IBlobAccessClient { } 

然后单独注册它们(以SimpleInject支持的任何方式)。

然后在您的消费者中,根据需要注入IBlobAccessClientSource和/或IBlobAccessClientDestination这将确保有两个单独注册 – 两个接口各一个。