【问题标题】:TinyIOC and multiple user specified factories for typeTinyIOC 和多个用户指定的工厂类型
【发布时间】:2013-06-22 02:56:42
【问题描述】:

我目前正在尝试使用 TinyIOC 连接自定义 ReactiveUI IMutableDependencyResolver。而且我正在为 ReactiveUI 想要向用户指定的工厂注册多个接口实现这一事实而苦苦挣扎。哪个 TinyIOC 似乎不支持。

每次再次调用 register 时,我的实现似乎都会覆盖以前的注册。有什么建议吗?

#region IMutableDependencyResolver implementation

public void Register(Func<object> factory, Type serviceType, string contract = null)
{
  TinyIOC.TinyIOCContainer.Current.Register(serviceType, (a, b)=>
  { 
    var result = factory();
    return result;
  }, contract);
}

#endregion

【问题讨论】:

    标签: c# reactiveui tinyioc


    【解决方案1】:

    基本上对于这样的解析器,您必须自己进行多重注册位 - 即,您必须注册“注册的服务列表”,而不是直接注册类型。这有点痛苦。

    如果您不需要通过构造函数进行服务注入,我建议您只使用内置的,它实际上是 Pretty Good™。

    更新:终于找到了一些我为解决 AutoFac 中类似问题而编写的代码: var builder = new ContainerBuilder(); var container = default(IContainer);

    #region Don't actually read this terrible code
    
    // NB: This garbage exists in order to work around the fact that
    // Autofac doesn't support multiple registrations for the same type
    // (i.e. GetAllServices), but RxUI relies on it.
    var registrations = new Dictionary<Tuple<Type, string>, List<Type>>();
    RxApp.ConfigureServiceLocator(
        (t, s) => s != null ? container.ResolveNamed(s, t) : container.Resolve(t),
        (t, s) => {
            var type = typeof(IEnumerable<>).MakeGenericType(t);
            var ret = (IEnumerable<Type>)container.ResolveNamed<IEnumerable<Type>>(type.FullName);
            return ret.Select(x => Activator.CreateInstance(x)).ToArray();
        },
        (c, t, s) => {
            // NB: This is the hackiest hack of hack to work around a bug in RxUI
            if (container != null) return;
    
            var pair = Tuple.Create(t, s);
            if (!registrations.ContainsKey(pair)) registrations[pair] = new List<Type>();
    
            registrations[pair].Add(c);
        });
    
    foreach (var kvp in registrations) {
        if (kvp.Value.Count == 1) {
            var reg = builder.RegisterType(kvp.Value[0]).As(kvp.Key.Item1);
            if (kvp.Key.Item2 != null) reg.Named(kvp.Key.Item2, kvp.Key.Item1);
        } else {
            var type = typeof(IEnumerable<>).MakeGenericType(kvp.Key.Item1);
            builder.RegisterInstance(kvp.Value).As<IEnumerable<Type>>().Named<IEnumerable<Type>>(type.FullName);
        }
    }
    
    #endregion
    

    【讨论】:

    • 嘿,保罗,这就是问题所在。我目前正在移植的应用程序大量使用构造函数注入:-)
    猜你喜欢
    • 1970-01-01
    • 2018-03-08
    • 2018-12-21
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 2020-01-29
    • 2021-03-18
    相关资源
    最近更新 更多