Tôi có một ứng dụng WPF có thể hoặc không thể bắt đầu bằng lệnh dòng lệnh args. Tôi đã từng sử dụng phương pháp OnStartup(StartupEventArgs e)
trong đoạn mã App.xaml, nhưng điều này đã gây ra sự cố tắt ứng dụng vì vậy tôi đã chuyển App.xaml thành "Trang" (thay vì "Định nghĩa ứng dụng") và đã viết Program
lớp chứa điểm nhập của ứng dụng của riêng tôi, điểm này sẽ trở thành vị trí gốc của thành phần mới của tôi.InvalidCastException at kernel.Get <type>
Vì thay đổi đó, tôi không thể bắt đầu ứng dụng, Ninject dường như không giải quyết được đối tượng chính của ứng dụng (hoặc nó có thể là một trong những phụ thuộc của nó?).
Trường hợp ngoại lệ này khiến tôi lãng phí rất nhiều thời gian và theo dõi ngăn xếp là tất cả Ninject-internal, tôi không biết phải sửa lỗi gì trong mã của mình, cách tôi ràng buộc loại hiện đang gây ra ngoại lệ này không thay đổi gần đây:
at DynamicInjector54d92ac63a2e47fda5ffbcc19b9942a9(Object[])
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.Resolve()
at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent)
at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent)
at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target)
at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.Resolve()
at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent)
at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent)
at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target)
at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.Resolve()
at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent)
at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent)
at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target)
at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.Resolve()
at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters)
at MyProgram.Program.Main(String[] args) in C:\Dev\MyProject\MyProject.WinPresentation\Program.cs:ligne 40
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(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 System.Threading.ThreadHelper.ThreadStart()
Dưới đây là điểm mấu chốt Main
phương pháp/app:
[STAThread]
public static void Main(string[] args)
{
var module = new MyAppNinjectModule(args);
var kernel = new StandardKernel(module);
var argsHelper = module.CommandLineArgs;
var logProvider = kernel.Get<ILogProvider>();
var logger = logProvider.GetLogger(typeof(Program).Name);
if (argsHelper.LoggingDisabledArgument.IsSpecified()) logProvider.DisableLogging();
logger.Info(log.LogAppStart);
var installer = kernel.Get<IInstaller>(); // >>> InvalidCastException here
if (argsHelper.QuietInterfaceArgument.IsSpecified())
{
// running with -quiet command-line switch: just execute and exit.
installer.Execute();
}
else
{
// instantiate a new App object (WPF), and run it.
// installer.Execute() may or may not be executed, depending on user actions.
var app = new App(installer);
app.Run();
}
}
các NinjectModule liên kết IInstaller
để thực hiện như vậy hoặc tương tự, tùy thuộc vào đối số dòng lệnh đã cung cấp (ví dụ SilentInstaller
khi QuietInterfaceArgument
được chỉ định, ManualInstaller
khi không, v.v.).
Thông thường Ninject cung cấp rất thông báo ngoại lệ hữu ích và chi tiết - khi đó là cuộc sống là ActivationException
là tốt. Nhưng điều này InvalidCastException
lá tôi không biết gì, tôi không phải là người thực hiện các diễn viên không hợp lệ, và tôi thậm chí không biết những loại đang được tham gia. Tôi chỉ biết rằng tôi có thể đã viết một số mã mà Ninject không thích, và có lẽ nó có liên quan đến cách tôi ràng buộc IInstaller
để triển khai, nhưng nếu tôi nhận xét phần "phân nhánh" của NinjectModule để buộc ràng buộc việc thực hiện cụ thể (ManualInstaller
) mà tôi đang sau, nó vẫn thất bại với điều này InvalidCastException
.
constructor của thực hiện:
public ManualInstaller(IView<MainWindowViewModel> view,
IProcessHelper processHelper,
ISettingsHelper settingsHelper,
ILogProvider logProvider,
ISetupBootstrapper installer,
bool notifySuccess)
: base(notifySuccess, processHelper, settingsHelper, logProvider, installer)
Mã ràng buộc tương ứng (phần còn lại phụ thuộc đã được ràng buộc và không có ActivationException
vì vậy không chắc làm thế nào có liên quan này là vấn đề của tôi):
var msg = string.Empty;
if (CommandLineArgs.CompletionMessageArgument.IsSpecified())
msg = CommandLineArgs.CompletionMessageArgument.ParameterValue();
Bind<MainWindowViewModel>().ToSelf().WithConstructorArgument("completionMessage", msg);
Bind<IView<MainWindowViewModel>>().To<MainWindow>();
Bind<IInstaller>().To<ManualInstaller>()
.WithConstructorArgument("notifySuccess", notifySuccess);
Don Đừng ngần ngại cho tôi biết nếu cần điều gì khác để tìm hiểu điều gì đang diễn ra ...
CHỈNH SỬA
Giải quyết phụ thuộc của bộ cài đặt cá nhân mang lại biết thêm thông tin:
// resolve installer dependencies:
var view = kernel.Get<IView<MainWindowViewModel>>(); // >>> InvalidCastException here
var processHelper = kernel.Get<IProcessHelper>();
var settingsHelper = kernel.Get<ISettingsHelper>();
var bootstrapper = kernel.Get<ISetupBootstrapper>();
var installer = new ManualInstaller(view, processHelper, settingsHelper, logProvider, bootstrapper, true);
Vì vậy, tôi ít nhất có thể thu hẹp nó xuống để một sự phụ thuộc cụ thể của các loại Tôi đang cố gắng để giải quyết: vấn đề là một trong hai với Life View , hoặc với sự phụ thuộc duy nhất của nó, ViewModel.Vì vậy, tôi đã làm điều này:
// resolve ViewModel dependencies:
var processHelper = kernel.Get<IProcessHelper>(); // >>> InvalidCastException here
var settingsHelper = kernel.Get<ISettingsHelper>();
var messenger = kernel.Get<INetworkMessenger>();
var factory = kernel.Get<IBuildServerFactory>();
var dialogs = kernel.Get<ICommonDialogs>();
Vì vậy, dường như nó là việc thực hiện IProcessHelper đó là vấn đề - một lần nữa:
// resolve ProcessHelper dependencies:
var processWrapper = kernel.Get<IProcessWrapper>();
var wmiWrapper = kernel.Get<IWindowsManagementInstrumentationWrapper>();
var helper = new ProcessHelper(processWrapper, wmiWrapper, logProvider, 300);
Và bây giờ tôi không còn nhận được sự InvalidCastException
.
Dưới đây là các lĩnh vực lớp constructor và có vấn đề:
private readonly ILogProvider _logProvider;
private readonly IProcessWrapper _process;
private readonly IWindowsManagementInstrumentationWrapper _wmi;
public int TimeoutSeconds { get; private set; }
public ProcessHelper(IProcessWrapper process,
IWindowsManagementInstrumentationWrapper wmiWrapper,
ILogProvider logProvider,
int timeout)
{
_logProvider = logProvider;
_process = process;
_wmi = wmiWrapper;
TimeoutSeconds = timeout;
}
Và làm thế nào các NinjectModule liên kết với nó:
Bind<IProcessHelper>().To<ProcessHelper>()
.WithConstructorArgument("timeout", Properties.Settings.Default.ProcessTimeoutSeconds);
** RE-EDIT **
Với sự giúp đỡ của @ bình luận của jure, tôi đã thấy rằng loại ProcessTimeoutSeconds
trong Properties.Settings.Default
thực sự được đặt thành string
- khi hiển nhiên nó muốn có một int
. Đập vào!
Chỉ cần đoán, có thể một số đối số hàm tạo trong thiết lập ràng buộc của bạn không thuộc loại được mong đợi .. WithConstructorArgument không thể kiểm tra xem đối tượng bạn đang truyền đến có phải là kiểu hợp lệ cho đối số hàm tạo hay không. Đó có thể là nguồn của InvalidCastException. Bạn nên kiểm tra xem các đối tượng "msg" và "notifySuccess" có hợp lệ đối với các hàm tạo MainWindowViewModel và ManualInstaller hay không. – jure
@jure bang trên (xem lại chỉnh sửa), và bạn đoán rằng TRƯỚC KHI tôi đăng chỉnh sửa đầu tiên ... bạn là một ngôi sao! Đăng bài đó như một câu trả lời và tôi sẽ sẵn sàng upvote và chấp nhận nó! –
vui vì bạn đã tìm thấy nguyên nhân của sự cố ... và tôi đã đăng câu trả lời cũng như – jure