Подписка на событие OpenNetCF.IOC не срабатывает

Я разрабатываю приложение Vb.net .Net 3.5 PDA с использованием инфраструктуры OpenNetCF IOC. Я настроил и событие для обработки навигации по интеллектуальным частям, но когда я вызываю событие, EventSubscription не срабатывает.

Я уверен, что пропустил что-то простое, но был бы признателен за совет.

Imports OpenNETCF
Imports OpenNETCF.IoC
Imports OpenNETCF.IoC.UI

Public Class MainContainer

    <EventPublication(EventNames.Navigate)> _
    Public Event NavigateToSmartPart As EventHandler(Of GenericEventArgs(Of SmartPart))

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        RootWorkItem.Items.Add(workspace, WorkspaceNames.StackWorkspace)

        RootWorkItem.Services.AddOnDemand(Of XMLWrapper)()
        RootWorkItem.Services.AddOnDemand(Of DataInterface)()

        'RootWorkItem.SmartParts.AddNewDisposable(Of ViewCamera)()
        RootWorkItem.SmartParts.AddNew(Of ViewGoodInInspection)()
        RootWorkItem.SmartParts.AddNew(Of ViewLogon)()
        RootWorkItem.SmartParts.AddNew(Of ViewPartCentre)()
        RootWorkItem.SmartParts.AddNew(Of ViewSplash)()

    End Sub

    Private Sub MainContainer_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

        RootWorkItem.Services.Get(Of DataInterface)().InitialseApplication()

        If RootWorkItem.Services.Get(Of XMLWrapper)().LoadPartCentreID.Equals(UInt16.MinValue) Then
            RaiseEvent NavigateToSmartPart(Me, New GenericEventArgs(Of SmartPart)(RootWorkItem.SmartParts.Get(Of ViewPartCentre).First))
        Else
            RaiseEvent NavigateToSmartPart(Me, New GenericEventArgs(Of SmartPart)(RootWorkItem.SmartParts.Get(Of ViewSplash).First))
        End If

    End Sub

    <EventSubscription(EventNames.Navigate, ThreadOption.Caller)> _
    Public Sub NavigateSmartPart(Of T As SmartPart)()
        'Public Sub NavigateSmartPart(Of T As SmartPart)()
        workspace.Show(RootWorkItem.SmartParts.Get(Of t).First)
    End Sub

End Class

person Phil Murray    schedule 04.10.2011    source источник


Ответы (2)


Ок, разобрался.

Это было сделано для требования, чтобы объект запуска был Sub Main, и этот класс наследовался от SmartClientApplication (Of Form).

Imports OpenNETCF.IoC.UI

Namespace OpenNetCF_Events_CSharp
    Public Class Startup
        Inherits SmartClientApplication(Of Form1)

        Public Shared Sub Main()
            Dim appStarter As New Startup
            appStarter.Start()
        End Sub

    End Class

End Namespace

Это необходимо для того, чтобы элементы, смарт-компоненты и службы могли правильно подключить событие.

Фил

person Phil Murray    schedule 06.10.2011
comment
На самом деле это не на 100% правда. Чтобы быть связанными вместе, экземпляры издателя и подписчика просто должны быть добавлены в один и тот же контейнер IoC. Отсутствие добавления одного (подписчика или издателя) является наиболее распространенной причиной того, что событие не срабатывает. Извините, что не увидел этот вопрос раньше. - person ctacke; 06.10.2011

Спасибо за ответ Крис,

Я также получаю сообщение об ошибке при создании новых смарт-деталей с настройкой EventPublication.

ГЛАВНАЯ ФОРМА

RootWorkItem.SmartParts.AddNew(Of ViewLogon)()

<EventSubscription(EventNames.Navigate, ThreadOption.UserInterface)> _
Public Sub NavigateSmartPart(ByVal sender As Object, ByVal e As GenericEventArgs(Of String))
    workspace.Show(RootWorkItem.SmartParts.Get(e.Value))
End Sub

НОВАЯ УМНАЯ ЧАСТЬ

<EventPublication(EventNames.Navigate)> _
Public Event NavigateToSmartPart As EventHandler(Of GenericEventArgs(Of String))

Выдает ошибку Target Invokation (Inner Exception NullReferenceException) в приведенном ниже методе в строке else if (ctors.Count() == 1).

internal static object CreateObject(Type t, WorkItem root)
{
    object instance = null;

    // first check the cache
    if(m_constructorCache.ContainsKey(t))
    {
        return CreateObjectFromCache(t, root);
    }

    ConstructorInfo ci;

    if (t.IsInterface)
    {
        throw new IOCException(string.Format("Cannot create an instance of an interface class ({0}). Check your registration code.", t.Name));
    }


    // see if there is an injection ctor
    var ctors = (from c in t.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                 where c.IsPublic == true
                 && c.GetCustomAttributes(typeof(InjectionConstructorAttribute), true).Count() > 0
                 select c);

    if (ctors.Count() == 0)
    {
        // no injection ctor, get the default, parameterless ctor
        var parameterlessCtors = (from c in t.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                                  where c.GetParameters().Length == 0
                                  select c);
        if (parameterlessCtors.Count() == 0)
        {
            throw new ArgumentException(string.Format("Type '{0}' has no public parameterless constructor or injection constructor.\r\nAre you missing the InjectionConstructor attribute?", t));
        }

        // create the object
        ci = parameterlessCtors.First();
        try
        {
            instance = ci.Invoke(null);
            m_constructorCache.Add(t, new InjectionConstructor { CI = ci });
        }
        catch (TargetInvocationException ex)
        {
            throw ex.InnerException;
        }
    }
    else if (ctors.Count() == 1)
    {
        // call the injection ctor
        ci = ctors.First();
        ParameterInfo[] paramList = ci.GetParameters();
        object[] inputs = GetParameterObjectsForParameterList(paramList, root, t.Name);
        try
        {
            instance = ci.Invoke(inputs);
            m_constructorCache.Add(t, new InjectionConstructor { CI = ci, ParameterList = paramList });
        }
        catch (TargetInvocationException ex)
        {
            throw ex.InnerException;
        }
    }
    else
    {
        throw new ArgumentException(string.Format("Type '{0}' has {1} defined injection constructors.  Only one is allowed", t.Name, ctors.Count()));
    }
    // NOTE: we don't do injections here, as if the created object has a dependency that requires this instance it would fail becasue this instance is not yet in the item list.

    return instance;
}

Стек вызовов

   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)
   at OpenNETCF.IoC.ManagedObjectCollection`1.AddNew[TTypeToBuild]()
   at GoodsInInspection.MainContainer..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.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
   at OpenNETCF.IoC.ObjectFactory.CreateObject(Type t, WorkItem root)
   at OpenNETCF.IoC.ManagedObjectCollection`1.AddNew(Type typeToBuild, String id, Boolean expectNullId, Boolean wrapDisposables)
   at OpenNETCF.IoC.ManagedObjectCollection`1.AddNew(Type typeToBuild)
   at OpenNETCF.IoC.ManagedObjectCollection`1.AddNew[TTypeToBuild]()
   at OpenNETCF.IoC.UI.SmartClientApplication`1.Start(IModuleInfoStore store)
   at OpenNETCF.IoC.UI.SmartClientApplication`1.Start()
   at GoodsInInspection.Startup.Main()

Если я удалю атрибут EventPublication из события, умная часть будет успешно создана.

person Phil Murray    schedule 10.10.2011
comment
Не берите в голову. Я отсортировал его. Похоже, проблема с использованием Service.AddOnDemand вместо Service.AddNew - person Phil Murray; 10.10.2011