- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在容器中注册一个类的多个实例。每个实例都由其 ID 属性标识。
public interface MyInterface
{
string Id { get; }
}
public class MyImpl : MyInterface
{
public string Id { get; }
public MyImpl(string id) => Id = id;
}
而且,我想在另一个类的构造函数中接收这个实例。
using DryIoc;
public class User
{
public MyInterface Obj { get; }
public User(string id, Func<string, MyInterface> getObj)
=> Obj = getObj(id);
}
class Program
{
static void Main()
{
Container container = new();
container.RegisterInstance<MyInterface>(new MyImpl("A"), serviceKey: "A");
container.RegisterInstance<MyInterface>(new MyImpl("B"), serviceKey: "B");
container.Register<User>();
var user = container.Resolve<Func<string, User>>()("A");
}
}
此代码抛出 ContainerException。
DryIoc.ContainerException: code: Error.UnableToResolveFromRegisteredServices;
message: Unable to resolve MyInterface with passed arguments [String@0] (IsWrappedInFunc, IsDirectlyWrappedInFunc)
in wrapper Func<String, MyInterface> as parameter "getObj" WrapperExpressionFactoryWithSetup FactoryId=158 with passed arguments [String@0] (IsWrappedInFunc)
in User FactoryId=146 with passed arguments [String@0] (IsWrappedInFunc, IsDirectlyWrappedInFunc)
in resolution root wrapper System.Func`2[System.String,User] WrapperExpressionFactoryWithSetup FactoryId=158 with passed arguments [String@0]
from container without scope
with normal and dynamic registrations:
("B", {FactoryID=145, ImplType=MyImpl, Reuse=Singleton {Lifespan=1000}}) ("A", {FactoryID=144, ImplType=MyImpl, Reuse=Singleton {Lifespan=1000}})
可以通过在Container.Resolve()中指定serviceKey来获取想要的实例。但是,由于 User 类是通过构造函数注入(inject)到另一个实例中的,我们不想直接调用 Contaienr 的方法。
我认为我可以在 Register() 的参数中适本地指定 made。应该如何指定?
编辑
现在,创建一个对象容器并解决这个问题。
public static class Holder<T> where T : class
{
private static readonly Dictionary<string, T> _dictionary = new();
public static void Add(string id, T obj) => _dictionary.Add(id, obj);
public static void Remove(string id) => _dictionary.Remove(id);
public static T Get(string id) => _dictionary[id];
}
interface IService
{
string Id { get; }
}
class Service : IService
{
public string Id { get; }
public Service(string id) => Id = id;
}
interface IServiceUser
{
IService Service { get; }
}
class ServiceUser : IServiceUser
{
public IService Service { get; }
public ServiceUser(IService service) => Service = service;
}
class ViewModel
{
public ViewModel(IServiceUser serviceUser)
{
Console.WriteLine(serviceUser.Service.Id);
}
}
static class Program
{
static void Main()
{
Holder<IService>.Add("A", new Service("A"));
Holder<IService>.Add("B", new Service("B"));
Container container = new();
container.Register(made: Made.Of(() => Holder<IService>.Get(Arg.Of<string>())));
container.Register<IServiceUser, ServiceUser>();
container.Register<ViewModel>();
var createVm = container.Resolve<Func<string, ViewModel>>();
var vmA = createVm("A");
var vmB = createVm("B");
}
}
但是既然容器可以容纳对象,我在想,如果我能将Func中传递的值传递给serviceKey,就不需要Holder类了。
最佳答案
您可以替换 Func<string, MyInterface> getObj
与 IEnumerable<KeyValuePair<<string, MyInterface>>> getObj
因此它将作为字典来获取您的实例(DryIoc 目前不直接支持 Dictionary
,但将来可能会支持)。
这里是完整的例子(https://dotnetfiddle.net/kxZCck):
using System;
using System.Collections.Generic;
using System.Linq;
using DryIoc;
public interface MyInterface
{
string Id { get; }
}
public class MyImpl : MyInterface
{
public string Id { get; }
public MyImpl(string id) => Id = id;
}
public class User
{
public MyInterface Obj { get; }
public User(string id, IEnumerable<KeyValuePair<string, MyInterface>> getObj)
=> Obj = getObj.First(kv => kv.Key == id).Value;
}
class Program
{
static void Main()
{
Container container = new();
container.RegisterInstance<MyInterface>(new MyImpl("A"), serviceKey: "A");
container.RegisterInstance<MyInterface>(new MyImpl("B"), serviceKey: "B");
container.Register<User>();
var user = container.Resolve<Func<string, User>>()("A");
Console.WriteLine(((MyImpl)user.Obj).Id);
}
}
这是要跟踪的词典功能问题:https://github.com/dadhi/DryIoc/issues/504
这是您不需要的解决方案 Holder
并且不需要用字典 (https://dotnetfiddle.net/IAhGTg) 污染您的服务构造函数:
using System;
using System.Collections.Generic;
using DryIoc;
interface IService
{
string Id { get; }
}
class Service : IService
{
public string Id { get; }
public Service(string id) => Id = id;
}
interface IServiceUser
{
IService Service { get; }
}
class ServiceUser : IServiceUser
{
public IService Service { get; }
public ServiceUser(IService service) => Service = service;
}
class ViewModel
{
public ViewModel(IServiceUser serviceUser)
{
Console.WriteLine(serviceUser.Service.Id);
}
}
static class Program
{
static void Main()
{
var container = new Container();
container.RegisterInstance<IService>(new Service("A"), serviceKey: "A");
container.RegisterInstance<IService>(new Service("B"), serviceKey: "B");
// Register a delegate returning a service without key selecting the result
// from the collection of keyed services with their keys and using the key provided by Func<string,...>
container.RegisterDelegate<KeyValuePair<string, IService>[], string, IService>(
(services, serviceKey) => Array.Find(services, s => s.Key == serviceKey).Value
);
container.Register<IServiceUser, ServiceUser>();
container.Register<ViewModel>();
var createVm = container.Resolve<Func<string, ViewModel>>();
var vmA = createVm("A");
var vmB = createVm("B");
}
}
关于c# - DryIoc - 使用 ID 注册多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72959325/
我有一个以 DryIoc 作为容器的 Prism 应用程序。 我要 IHttpClientFactory提供HttpClient s 给我的 输入客户 ,它们是这样的: public class Ex
我正在尝试使用 DryIOC 实现事件聚合器。我有一个事件调度程序,如下所示: public class DryIocEventDispatcher : IEventDispatcher {
StructureMap 在 Container 类上有一个非常有用的调试方法,称为 WhatDoIHave() 它显示了容器中的每种类型及其生命周期、guid 和一堆其他信息。这对调试很有用。 这里
我想注册两个服务,A & B ,有不同的生命周期。 我的用例类似于“浏览器”和“标签”。 我在可执行生命周期(浏览器)上有一个范围,每个选项卡都有一个“子范围”。 我要 A成为浏览器范围内的单例(浏览
假设我有这项服务和两种策略: public class SomeService : ISomeService { public SomeService(ICurrentDbContext co
我正在尝试将对象解析为 Func<> 的结果.但我不知道该怎么做。 例如,这里我有一个变量(函数参数)lazyInt (这可能是某种长时间运行计算的结果)并且在以后可能使用之前不需要哪个结果。
尝试在 Prism.Forms ( https://github.com/joacar/Prism/tree/pr-517 ) 中构建对 DryIoc 的支持,并偶然发现了一个我无法弄清楚该怎么做的场
我在使用 DryIoC 时遇到了一个相当令人费解的情况。 好吧,实际上,这是我第一次使用 IoC 容器,所以我可能只是误解了一切:从依赖注入(inject)到 IoC 容器,再到 DryIoC 本身。
嘿,我已经从 Autofac 切换到 DryIoc。我的代码以前可以工作,但现在导致异常“解析时检测到递归依赖项”。 (代码已简化) public class AFactory { public
查看 wiki对于 DryIoc,示例显示的似乎与我需要的相反,我想知道是否可能相反? Wiki (部分示例) public interface X {} public interface Y {}
查看 wiki对于 DryIoc,示例显示的似乎与我需要的相反,我想知道是否可能相反? Wiki (部分示例) public interface X {} public interface Y {}
给出下面的小例子,有没有办法在 MyService2 中标记(属性,名称约定,...)MyInterface 参数,以便它解析正确,或者是传递 MyInterface[] 的唯一方法?我知道CaSTL
我有一个 Container注册一个 Presenter View 类: Container.Register(); Presenter的构造函数为其 View 接受一个参数: public List
我正在探索 DryIoc 在 .NET WebAPI 应用程序中的使用,并注意到初始化步骤有一个奇怪的行为。在一个简单的测试 webapi 应用程序中,我有以下 DryIoc 注册类,它在 WebAp
问题 我正在尝试使用 DryIoc 注册一个单例,但容器返回了我的单例类的多个实例。单例类注册为多个不同服务接口(interface)的实现类型。当从 DryIoc 请求任何上述服务接口(interf
很抱歉,我没有太多代码可以分享,因为我不确定这将如何工作。 我有一个名为 API.Tests 的测试项目,我正在 API 项目中为 NewsController 编写测试。我不确定如何将依赖项从测试传
我想使用一些具有良好性能结果的 .NET IoC 容器。我读了this article关于 IoC 容器性能,DryIoc 和 LightInject 似乎是最好的。但是我没有找到关于它们的一些评论,
我想在容器中注册一个类的多个实例。每个实例都由其 ID 属性标识。 public interface MyInterface { string Id { get; } } public cla
我想将 Microsoft.Extensions.Logging 与 DryIoc 容器一起使用。 默认方式是将工厂注册为实例,注入(inject)并创建记录器: ILoggerFactory log
我们目前正在使用 Autofac 并利用 AutofacSerilogIntegration 在将 ILogger 注入(inject)混凝土时自动设置日志记录上下文。集成使用记录器注入(inject
我是一名优秀的程序员,十分优秀!