我通过Ninject在像这样的对象上注入了工厂绑定。
[Inject]
public Func<TNewDocument> DocumentFactory { get; set; }
我们称之为
var newDoc = DocumentFactory()
第一次调用DocumentFactory()成功。
后续调用会导致Ninject报告在激活时TNewDocument
有多个绑定。
我修改了我的代码以直接调用内核而不是使用工厂。我做了
var docs Kernel.GetAll<TNewDocument>().ToList();
if(docs.Count!=1){
Console.WriteLine("boo");
}
return docs[0]; // A work around to stop the app crashing
我检查GetAll
电话实际返回的对象数量。每次调用以创建新对象时,此数字都会增加。
第一次返回一个对象。第二次是两个对象,第三次是三个等等。
我们将存储库分成两部分以发现重大变化。这是ReactiveUI 7.1 to 7.2的升级版。除了nuget所做的更改之外,没有其他代码更改。
但是ReactiveUI只与Ninject有基本关系。我必须为RxUI提供服务定位器,如下所示。
var customResolver = new FuncDependencyResolver(
(service, contract) =>
{
if (contract != null) return kernel.GetAll(service, contract);
var items = kernel.GetAll(service);
var list = items.ToList();
return list;
},
(factory, service, contract) =>
{
var binding = kernel.Bind(service).ToMethod(_ => factory());
if (contract != null) binding.Named(contract);
});
Locator.Current = customResolver;
除此之外there is no relation。
我看不出为什么升级RxUI会导致这个问题。有什么想法吗?
答案 0 :(得分:0)
这是最新版本中引入的ReactiveUI中的错误/重大更改。
https://github.com/reactiveui/ReactiveUI/pull/1282
我用
覆盖了默认的ReactiveUI View Locator /// <summary>
/// Due to bugs / magic in the ReactiveUI view locator we write our own.
/// The ReactiveUI view locator causes errors if the ViewModel name
/// doesn't end with "ViewModel". It ends up thinking the ViewModel
/// and the View are the same class and then very bad stuff happens.
/// </summary>
public class WeinCadViewLocator : IViewLocator
{
private readonly IKernel _Kernel;
public WeinCadViewLocator(IKernel kernel)
{
_Kernel = kernel;
}
public IViewFor ResolveView<T>(T viewModel, string contract = null) where T : class
{
Type generic = typeof(IViewFor<>);
Type[] args = new[] {viewModel.GetType()};
var realType = generic.MakeGenericType( args );
if (contract == null)
{
return (IViewFor) _Kernel.Get( realType );
}
else
{
return (IViewFor) _Kernel.Get( realType, contract );
}
}
}
现在初始化
public static void Init(IKernel kernel)
{
var customResolver = new FuncDependencyResolver
(
(service, contract) =>
{
if (contract != null)
return kernel.GetAll( service, contract );
var items = kernel.GetAll( service );
var list = items.ToList();
return list;
}
, (factory, service, contract) =>
{
var binding = kernel
.Bind( service )
.ToMethod( _ => factory() );
if (contract != null)
binding.Named( contract );
} );
Locator.CurrentMutable.InitializeSplat();
Locator.CurrentMutable.InitializeReactiveUI();
Locator.CurrentMutable = customResolver;
Locator.CurrentMutable
.RegisterLazySingleton
(() => new WeinCadViewLocator(kernel)
, typeof(IViewLocator));
var log = SerilogExtensions.DefaultLogger;
Log.Logger = log;
SerilogSplatLogger.Register(log);
}