我正在创建一个Windows Mobile应用程序,在使用OpenNETCF.IoC.UI创建SmartPart时,EventPublication's库遇到了一些问题。
我的订阅位于容器的主要位置,而发布位于一个继承自OpenNETCF.IoC.UI.SmartPart的对象
应用程序启动
Public Class Startup
Inherits SmartClientApplication(Of MainContainer)
Public Shared Sub Main()
Dim appStarter As New Startup
appStarter.Start()
End Sub
End Class
在MainContiner表单上订阅
<EventSubscription(EventNames.Navigate, ThreadOption.UserInterface)> _
Public Sub NavigateSmartPart(ByVal sender As Object, ByVal e As GenericEventArgs(Of String))
.....
End Sub
发布商
Namespace Views
Public Class ViewLogon
<EventPublication(EventNames.Navigate)> _
Friend Event NavigateToSmartPart As EventHandler(Of GenericEventArgs(Of String))
Public Overrides Sub OnActivated()
End Sub
End Class
End Namespace
问题
如果我尝试编写这个智能部分,我会在OpenNETCF.IoC.ObjectFactory.AddCollectionEventHandlers<TKey, TItem>
行的source.EventInfo.AddEventHandler(instance, intermediate);
方法中得到NullReferenceException。
删除EventPublication
没有任何问题。
private static void AddCollectionEventHandlers<TKey, TItem>(object instance, IEnumerable<KeyValuePair<TKey, TItem>> collection, PublicationDescriptor[] sourceEvents, SubscriptionDescriptor[] eventSinks)
{
if (collection == null) return;
var invokerControl = RootWorkItem.Items.Get<TheInvoker>("IOCEventInvoker");
foreach (var item in collection)
{
if (instance.Equals(item.Value)) continue;
if((item.Value is WorkItem) && (collection is ServiceCollection))
{
// this prevents recursion (and a stack overflow) for WorkItems
continue;
}
foreach (var source in sourceEvents)
{
// wire up events
foreach (var sink in GetEventSinksFromTypeByName(item.Value.GetType(), source.Publication.EventName, ThreadOption.Caller))
{
Delegate d = Delegate.CreateDelegate(source.EventInfo.EventHandlerType, item.Value, sink);
source.EventInfo.AddEventHandler(instance, d);
}
foreach (var sink in GetEventSinksFromTypeByName(item.Value.GetType(), source.Publication.EventName, ThreadOption.UserInterface))
{
// wire up event handlers on the UI thread
Delegate d = Delegate.CreateDelegate(source.EventInfo.EventHandlerType, item.Value, sink);
if (source.EventInfo.EventHandlerType == typeof(EventHandler))
{
// unsure why so far but this fails if the EventHandler signature takes a subclass of EventArgs as the second param
// and if you use just EventArgs, the arg data gets lost
BasicInvoker invoker = new BasicInvoker(invokerControl, d);
Delegate intermediate = Delegate.CreateDelegate(source.EventInfo.EventHandlerType, invoker, invoker.HandlerMethod);
source.EventInfo.AddEventHandler(instance, intermediate);
}
else if ((source.EventInfo.EventHandlerType.IsGenericType) && (source.EventInfo.EventHandlerType.GetGenericTypeDefinition().Name == "EventHandler`1"))
{
BasicInvoker invoker = new BasicInvoker(invokerControl, d);
Delegate intermediate = Delegate.CreateDelegate(source.EventInfo.EventHandlerType, invoker, invoker.HandlerMethod);
source.EventInfo.AddEventHandler(instance, intermediate);
}
}
}
// back-wire any sinks
foreach (var sink in eventSinks)
{
foreach (var ei in GetEventSourcesFromTypeByName(item.Value.GetType(), sink.Subscription.EventName))
{
try
{
// (type, consumer instance, consumer method)
Delegate d = Delegate.CreateDelegate(ei.EventHandlerType, instance, sink.MethodInfo);
if (sink.Subscription.ThreadOption == ThreadOption.Caller)
{
ei.AddEventHandler(item.Value, d);
}
else
{
// wire up event handlers on the UI thread
if ((ei.EventHandlerType.IsGenericType) && (ei.EventHandlerType.GetGenericTypeDefinition().Name == "EventHandler`1")
|| (ei.EventHandlerType == typeof(EventHandler))
#if !WINDOWS_PHONE
|| (ei.EventHandlerType == typeof(KeyEventHandler))
#endif
)
{
// unsure why so far but this fails if the EventHandler signature takes a subclass of EventArgs as the second param
// and if you use just EventArgs, the arg data gets lost
BasicInvoker invoker = new BasicInvoker(invokerControl, d);
Delegate intermediate = Delegate.CreateDelegate(ei.EventHandlerType, invoker, invoker.HandlerMethod);
ei.AddEventHandler(item.Value, intermediate);
}
else
{
throw new ArgumentException("ThreadOption.UserInterface only supported for EventHandler and EventHandler<T> events");
}
}
}
catch (ArgumentException)
{
throw new ArgumentException(string.Format("Unable to attach EventHandler '{0}' to '{1}'.\r\nDo the publisher and subscriber signatures match?", ei.Name, instance.GetType().Name));
}
}
}
WorkItem wi = item.Value as WorkItem;
if (wi != null)
{
AddEventHandlers(instance, wi, false);
}
}
}
堆栈跟踪
at System.Reflection.EventInfo.AddEventHandler(Object target, Delegate handler)
at OpenNETCF.IoC.ObjectFactory.AddCollectionEventHandlers[TKey,TItem](Object instance, IEnumerable`1 collection, PublicationDescriptor[] sourceEvents, SubscriptionDescriptor[] eventSinks)
at OpenNETCF.IoC.ObjectFactory.AddEventHandlers(Object instance, WorkItem root, Boolean walkUpToRoot)
at OpenNETCF.IoC.ObjectFactory.AddEventHandlers(Object instance, WorkItem root)
at OpenNETCF.IoC.ObjectFactory.DoInjections(Object instance, WorkItem root)
at OpenNETCF.IoC.ManagedObjectCollection`1.Add(ISmartPart item, String id, Boolean expectNullId)
at OpenNETCF.IoC.ManagedObjectCollection`1.AddNew(Type typeToBuild, String id, Boolean expectNullId, Boolean wrapDisposables)
at OpenNETCF.IoC.ManagedObjectCollection`1.AddNew(Type typeToBuild, String id)
at OpenNETCF.IoC.ManagedObjectCollection`1.AddNew[TTypeToBuild](String id)
at StockMovement.IoC.Container.RegisterViews()
at StockMovement.IoC.Container.RegisterParts(DeckWorkspace workspace)
at StockMovement.MainContainer.MainContainerLoad(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form._SetVisibleNotify(Boolean fVis)
at System.Windows.Forms.Control.set_Visible(Boolean value)
at System.Windows.Forms.Application.Run(Form fm)
at OpenNETCF.IoC.UI.SmartClientApplication`1.OnApplicationRun(Form form)
at OpenNETCF.IoC.UI.SmartClientApplication`1.Start(IModuleInfoStore store)
at OpenNETCF.IoC.UI.SmartClientApplication`1.Start()
at StockMovement.Startup.Main()
答案 0 :(得分:1)
行, 通过剪切运气我已经弄明白了。然后事件需要公开才能连接pub / sub。
<EventPublication(EventNames.Navigate)> _
Friend Event NavigateToSmartPart As EventHandler(Of GenericEventArgs(Of String))
更改为以下作品。
<EventPublication(EventNames.Navigate)> _
Public Event NavigateToSmartPart As EventHandler(Of GenericEventArgs(Of String))