如何在MVVM Light中使用Ninject

时间:2013-08-07 22:07:57

标签: windows-phone-7 ninject mvvm-light service-locator

我正在尝试用WP7应用程序中的Ninject 3替换SimpleIoc。到目前为止,我的应用程序中有Portable.CommonServiceLocator.NinjectAdapter,它包含一个服务定位器,但每次我尝试使用时,我的应用程序崩溃,所以我必须遗漏一些东西。

简单的Ioc方式

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using MvvmLight1.Model;

namespace MvvmLight1.ViewModel
{
    public class ViewModelLocator
    {
        static ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            if (ViewModelBase.IsInDesignModeStatic)
            {
                SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
            }
            else
            {
                SimpleIoc.Default.Register<IDataService, DataService>();
            }

            SimpleIoc.Default.Register<MainViewModel>();
        }

        /// <summary>
        /// Gets the Main property.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
            "CA1822:MarkMembersAsStatic",
            Justification = "This non-static member is needed for data binding purposes.")]
        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }
    }

Ninject

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using MvvmLight1.Model;
using CommonServiceLocator.NinjectAdapter;

namespace MvvmLight1.ViewModel
{
    public class ViewModelLocator
    {
        static ViewModelLocator()
        {
            Ninject.StandardKernel k = new Ninject.StandardKernel();
            ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(k));
            k.Bind<IDataService, Design.DesignDataService>();
            k.Bind<MainViewModel>().ToSelf();

        }

        /// <summary>
        /// Gets the Main property.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
            "CA1822:MarkMembersAsStatic",
            Justification = "This non-static member is needed for data binding purposes.")]
        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }
    }
}

崩溃

  [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
        "CA1822:MarkMembersAsStatic",
        Justification = "This non-static member is needed for data binding purposes.")]
    public MainViewModel MainVm
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }


Microsoft.Practices.ServiceLocation.ActivationException was unhandled
  Message=Activation error occured while trying to get instance of type MainViewModel, key ""
  StackTrace:
       at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key)
       at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance[TService]()
       at PriceCheck.WindowsMobile.ViewModel.ViewModelLocator.get_MainVm()
       at PriceCheck.WindowsMobile.Views.MainPage..ctor()
       at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstructorInfo rtci, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
       at System.Reflection.RuntimeConstructorInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
       at System.Activator.InternalCreateInstance(Type type, Boolean nonPublic, StackCrawlMark& stackMark)
       at System.Activator.CreateInstance(Type type)
       at System.Windows.Navigation.PageResourceContentLoader.BeginLoad_OnUIThread(AsyncCallback userCallback, PageResourceContentLoaderAsyncResult result)
       at System.Windows.Navigation.PageResourceContentLoader.<>c__DisplayClass4.<BeginLoad>b__0(Object args)
       at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
       at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
       at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
       at System.Delegate.DynamicInvokeOne(Object[] args)
       at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
       at System.Delegate.DynamicInvoke(Object[] args)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
       at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
       at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
       at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
       at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)
  InnerException: System.TypeLoadException
       Message=Could not load type 'Ninject.Infrastructure.ReferenceEqualWeakReference' from assembly 'Ninject.Common, Version=3.0.0.0, Culture=neutral, PublicKeyToken=C7192DC5380945E7'.
       StackTrace:
            at Ninject.Activation.Strategies.ActivationCacheStrategy.Activate(IContext context, InstanceReference reference)
            at Ninject.Activation.Pipeline.<>c__DisplayClass2.<Activate>b__0(IActivationStrategy s)
            at Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 series, Action`1 action)
            at Ninject.Activation.Pipeline.Activate(IContext context, InstanceReference reference)
            at Ninject.Activation.Context.Resolve()
            at Ninject.KernelBase.<>c__DisplayClass13.<Resolve>b__d(IBinding binding)
            at System.Linq.Enumerable.<SelectIterator>d__d`2.MoveNext()
            at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
            at Ninject.ResolutionExtensions.Get(IResolutionRoot root, Type service, IParameter[] parameters)
            at CommonServiceLocator.NinjectAdapter.NinjectServiceLocator.DoGetInstance(Type serviceType, String key)
            at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key)
            at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance[TService]()
            at PriceCheck.WindowsMobile.ViewModel.ViewModelLocator.get_MainVm()
            at PriceCheck.WindowsMobile.Views.MainPage..ctor()
            at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstructorInfo rtci, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
            at System.Reflection.RuntimeConstructorInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
            at System.Activator.InternalCreateInstance(Type type, Boolean nonPublic, StackCrawlMark& stackMark)
            at System.Activator.CreateInstance(Type type)
            at System.Windows.Navigation.PageResourceContentLoader.BeginLoad_OnUIThread(AsyncCallback userCallback, PageResourceContentLoaderAsyncResult result)
            at System.Windows.Navigation.PageResourceContentLoader.<>c__DisplayClass4.<BeginLoad>b__0(Object args)
            at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
            at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
            at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
            at System.Delegate.DynamicInvokeOne(Object[] args)
            at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
            at System.Delegate.DynamicInvoke(Object[] args)
            at System.Windows.Threading.DispatcherOperation.Invoke()
            at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
            at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
            at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
            at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
            at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)

修改

我也尝试过这样做

 IKernel k = new StandardKernel();
 k.Bind<IDataService, Design.DesignDataService>();
 ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(k));
    var d = k.Get<IDataService>();

当“Get”尝试发生时,这给了我一个NULL异常。

An unhandled exception of type 'System.NullReferenceException' occurred in Ninject.Common.dll


System.NullReferenceException was unhandled
  Message=NullReferenceException
  StackTrace:
       at Ninject.Planning.Bindings.BindingConfiguration.GetProvider(IContext context)
       at Ninject.Planning.Bindings.Binding.GetProvider(IContext context)
       at Ninject.Activation.Context.GetProvider()
       at Ninject.Activation.Context.Resolve()
       at Ninject.KernelBase.<>c__DisplayClass13.<Resolve>b__d(IBinding binding)
       at System.Linq.Enumerable.<SelectIterator>d__d`2.MoveNext()
       at System.Linq.Enumerable.<CastIterator>d__b0`1.MoveNext()
       at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
       at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters)
       at MvvmLight2.ViewModel.ViewModelLocator..cctor()
       at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstructorInfo rtci, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
       at System.Reflection.RuntimeConstructorInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
       at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
       at MS.Internal.TypeProxy.<>c__DisplayClass30.<GetCreateObjectDelegate>b__2a()
       at MS.Internal.TypeProxy.CreateInstance(UInt32 customTypeId)
       at MS.Internal.XamlManagedRuntimeRPInvokes.CreateInstance(XamlTypeToken inXamlType, XamlQualifiedObject& newObject)
       at MS.Internal.XcpImports.Application_LoadComponentNative(IntPtr pContext, IntPtr pComponent, UInt32 cUriStringLength, String uriString, UInt32 cXamlStrLength, Byte* pXamlStr, UInt32 cAssemblyStrLength, String assemblyStr)
       at MS.Internal.XcpImports.Application_LoadComponent(IManagedPeerBase componentAsDO, String resourceLocator, UnmanagedMemoryStream stream, UInt32 numBytesToRead, String assemblyString)
       at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
       at MvvmLight2.App.InitializeComponent()
       at MvvmLight2.App..ctor()
       at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstructorInfo rtci, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
       at System.Reflection.RuntimeConstructorInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
       at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
       at MS.Internal.TypeProxy.<>c__DisplayClass30.<GetCreateObjectDelegate>b__2a()
       at MS.Internal.TypeProxy.CreateInstance(UInt32 customTypeId)
       at MS.Internal.FrameworkCallbacks.CreateKnownObject(IntPtr nativeRootPeer, UInt32 customTypeId, String initializationString, IntPtr& nativePeer, UInt32 isCreatedByParser)
       at MS.Internal.FrameworkCallbacks.CreateUnknownObject(String assemblyName, String typeName, IntPtr nativeRootPeer, String initializationString, UInt32& customTypeId, UInt32& coreTypeId, UInt32& typeFlags, IntPtr& nativePeer)

编辑3

出于某种原因,我重新制作了我的示例应用程序,而“Get”方法似乎并不存在。不确定我是否缺少某些进口或其他东西。

原始问题仍然存在。

1 个答案:

答案 0 :(得分:3)

我自己也遇到了这个问题。我最终发现的是,这是Portable.Ninject NuGet包3.0.7版中引入的错误。在我的情况下,恢复到Portable.Ninject包的3.0.6版本修复了该问题。该问题仅影响Windows Phone 7.完全相同的二进制文件在Windows Phone 8上运行没有问题。

http://www.nuget.org/packages/Portable.Ninject/3.0.6