OpenNETCF.IoC.UI SmartPart创建失败

时间:2013-06-24 10:06:44

标签: .net inversion-of-control opennetcf opennetcf.ioc

我正在创建一个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()

1 个答案:

答案 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))