2016-09-22 54 views
0

在我的代碼中,我試圖在viewModel的入口/出口處記錄viewModel名稱。統一容器如何解析註冊服務

我的記錄是

public interface ILoggerService : ILoggerFacade 
{ 
    void LogMessage(string message);  
    void LogEntry(); 
    void LogExit(); 
} 

public class LoggerService : ILoggerService 
{ 
    public void LogEntry() 
    { 
     var trace = new StackTrace(); 
     if (trace.FrameCount > 1) 
     { 
      string ns = trace.GetFrame(1).GetMethod().DeclaringType.Namespace; 
      string typeName = trace.GetFrame(1).GetMethod().DeclaringType.Name; 
      string message = string.Format("{0}.{1}.{2} Entry", ns, typeName, 
              trace.GetFrame(1).GetMethod().Name); 
      LogDebug(message, DefaultPriority); 
     } 
    } 

    // Same for LogExit 
} 

我的引導程序

public class Bootstrapper : UnityBootstrapper 
{ 
    protected override void ConfigureContainer() 
    { 
     base.ConfigureContainer(); 
     Container.RegisterInstance<ILoggerService>(_logger); 
    } 
    protected override ILoggerFacade CreateLogger() 
    { 
     _logger = new LoggerService(); 
     return _logger; 
    } 
} 

我的視圖模型&模型

public class HomeViewModel 
{ 
    private readonly ILoggerService _loggerService; 
    private readonly HomeModel _model; 
    public HomeViewModel(HomeModel model, ILoggerService logger) 
    { 
     logger.LogEntry(); 
     _model = model; 
     _loggerService = logger; 

     // Do some other stuff here. 

     logger.LogExit(); 
    } 
} 

public class HomeModel 
{ 
    private ILoggerService _logger; 
    public HomeModel(ILoggerService logger) 
    { 
     logger.LogEntry(); 
     _logger = logger; 
     logger.LogExit(); 
    } 
} 

錯誤我

Cat[Critical} Sev[Critical] Pri[100] Framework Time:[ 2016-09-22 13:33:39.860] Shisha.exe PId: 22220 ThreadId:7428 
#### An exception occurred while initializing module 'MainModule'. 
    - The exception message was: Resolution of the dependency failed, type = "Modules.Main.Views.HomeView", name = "(none)". 
Exception occurred while: Calling constructor Modules.Main.Models.HomeModel(Services.Logging.Interface.ILoggerService logger). 
Exception is: NullReferenceException - Object reference not set to an instance of an object. 
----------------------------------------------- 
At the time of the exception, the container was: 

    Resolving Modules.Main.Views.HomeView,(none) 
    Resolving parameter "viewModel" of constructor Modules.Main.Views.HomeView(Modules.Main.ViewModels.HomeViewModel viewModel) 
    Resolving Modules.Main.ViewModels.HomeViewModel,(none) 
    Resolving parameter "model" of constructor Modules.Main.ViewModels.HomeViewModel(Modules.Main.Models.HomeModel model, Microsoft.Practices.Prism.Regions.IRegionManager regionManager, Microsoft.Practices.Prism.Events.IEventAggregator eventAggregator, Services.Dialogs.Interface.IDialogService dialogService, Services.Logging.Interface.ILoggerService logger, Services.Localisation.Interfaces.ITranslator translator) 
     Resolving Modules.Main.Models.HomeModel,(none) 
     Calling constructor Modules.Main.Models.HomeModel(Services.Logging.Interface.ILoggerService logger) 

    - The Assembly that the module was trying to be loaded from was:Modules.Main, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
    Check the InnerException property of the exception for more information. If the exception occurred while creating an object in a DI container, you can exception.GetRootException() to help locate the root cause of the problem. 
    at Services.Logging.LoggerService.LogCritical(String message, Int32 priority) in C:\Projects\Utilities\DotNet\Services\Services.Logging\LoggerService.cs:line 257 
    at Services.Logging.LoggerService.LogCritical(String message) in C:\Projects\Utilities\DotNet\Services\Services.Logging\LoggerService.cs:line 250 
    at Shisha.Bootstrapper.InitializeModules() in C:\Projects\Shisha\Application\Shisha\Bootstrapper.cs:line 85 
    at Microsoft.Practices.Prism.UnityExtensions.UnityBootstrapper.Run(Boolean runWithDefaultConfiguration) 
    at Shisha.App.Application_Startup(Object sender, StartupEventArgs e) in C:\Projects\Shisha\Application\Shisha\App.xaml.cs:line 39 
    at System.Windows.Application.OnStartup(StartupEventArgs e) 
    at System.Windows.Application.<.ctor>b__1_0(Object unused) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.DispatcherOperation.InvokeImpl() 
    at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Windows.Threading.DispatcherOperation.Invoke() 
    at System.Windows.Threading.Dispatcher.ProcessQueue() 
    at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) 
    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) 
    at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) 
    at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) 
    at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) 
    at System.Windows.Application.RunDispatcher(Object ignore) 
    at System.Windows.Application.RunInternal(Window window) 
    at System.Windows.Application.Run(Window window) 
    at MyApp.App.Main() in C:\Projects\Shisha\Application\Shisha\obj\x86\Release\App.g.cs:line 0 

我Google和調試(通過添加日誌)大量終於知道它是

"trace.GetFrame(1).GetMethod().DeclaringType.Namespace;" 

是失敗..

它在「調試」模式工作正常(因爲PDB的文件),但在「發佈」模式下失敗。

而是從解決構造函數中的記錄,如果我們使用

Resolve<ILoggerService>(), 

它工作正常的。

目前還不清楚_container.Resolve()如何得到MethodBase信息和'從構造函數'解決沒有。 任何人都可以解釋我有什麼區別這兩個。

我完全錯過了什麼嗎?

+0

好吧,似乎有一些相關的代碼,你沒有顯示。例如,堆棧跟蹤顯示'Services.Logging.LoggerService.LogCritical(String message,Int32 priority)'中發生異常。你沒有顯示這個方法,你的ILoggerService接口也沒有聲明這個方法。據推測,這種方法依賴於一些空的對象。因此,'NullReferenceException'。這是我根據我所能看到的最佳猜測。 –

+0

謝謝Jason對它進行調查。我的ILoggerInterface有幾種方法,包括LogCritical。當應用程序即將崩潰時,我正在使用LogCritical()登錄到該文件。如果應用程序正在關閉LogEntry()。 – JSR

+0

最新的更新是,下面的代碼工作在發佈模式。可能是編譯器正在執行[MethodImpl(MethodImplOptions.NoInlining)]後面的某些事情] public class HomeModel { private ILoggerService _logger; public HomeModel(ILoggerService logger) { logger.LogEntry(); _logger = logger; logger.LogExit(); } } – JSR

回答

0

看來編譯器正在將構造函數轉換爲內聯構造函數。

通過使用[MethodImpl(MethodImplOptions.NoInlining)]並告訴編譯器不要內聯工作正常。

[MethodImpl(MethodImplOptions.NoInlining)] 
public class HomeModel 
{ 
    private ILoggerService _logger; 
    public HomeModel(ILoggerService logger) 
    { 
    logger.LogEntry(); 
    _logger = logger; 
    logger.LogExit(); 
    } 
}