Ошибка композиции MEF, не распространяющая внутреннее исключение (кроме сообщения)

Я работаю с MEF для загрузки модулей из разных источников в свое приложение. У меня есть пример (код ниже), где я создаю компонуемый класс, который генерирует исключение в конструкторе. Это исключение приводит к сбою композиции и, таким образом, вызывает исключение, говорящее "почему"... В заявлении говорится, что причиной является InvalidCastException... что верно.

Если я печатаю исключение, я знаю, почему оно терпит неудачу, но как мне получить ФАКТИЧЕСКОЕ исходное исключение (InvalidCastException), сгенерированное, чтобы я мог правильно его обработать, а не просто общий перехват, который пропустил бы другие исключения - в модуле, который запрашивает экземпляр указанного класса? Запрос CompositionException.Errors также не дает мне исходное исключение...

КОД:

using System.ComponentModel.Composition;
using Microsoft.Practices.ServiceLocation;

[Export(typeof(A))]
Class A
{
    [ImportingConstructor]
    public A(ISomeinterface x, ISomeOtherInterface y)
    {
        //// Throw some exception (in my code it happens to be an InvalidCastException)
        throw new InvalidCastException ("Unable to cast object of type 'Sometype' to type 'Someothertype'.");  
    }
}

Class B
{
    public B(IServiceLocator serviceLocator)
    {
        try
        {
            //// Here is where the exception would be thrown as an "ActivationException"
            A myAInstance = serviceLocator.GetInstance(A);
        }
        catch (ActivationException activationException)
        {
            //// Print original activation exception from trying to get the service
            System.Diagnostics.Debug.WriteLine(activationException);

            if (ex.InnerException is CompositionException)
            {
                CompositionException compositionException = (CompositionException)activationException.InnerException;

                //// *** Here is where I want to retrieve the InvalidCastException in order to handle it properly
                //// *** Also, componentException.InnerException is "null" and so is the componentException.Errors[0].Exception.InnerException 
            }
            else
            {
                throw;
            }
        }
    }
}

ВЫВОД:

Microsoft.Practices.ServiceLocation.ActivationException: Activation error occured while trying to get instance of type A, key "" ---> System.ComponentModel.Composition.CompositionException: The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) Unable to cast object of type 'Sometype' to type 'Someothertype'.

Resulting in: An exception occurred while trying to create an instance of type 'A'.

Resulting in: Cannot activate part 'A'.
Element: A -->  A -->  DirectoryCatalog (Path="C:\path\to\code\")

Resulting in: Cannot get export 'A (ContractName="A")' from part 'A'.
Element: A (ContractName="A") -->  A -->  DirectoryCatalog (Path="C:\path\to\code\")

   at System.ComponentModel.Composition.Hosting.CompositionServices.GetExportedValueFromComposedPart(ImportEngine engine, ComposablePart part, ExportDefinition definition)
   at System.ComponentModel.Composition.Hosting.CatalogExportProvider.GetExportedValue(CatalogPart part, ExportDefinition export, Boolean isSharedPart)
   at System.ComponentModel.Composition.ExportServices.GetCastedExportedValue[T](Export export)
   at System.ComponentModel.Composition.ExportServices.<>c__DisplayClass10`2.<CreateSemiStronglyTypedLazy>b__d()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Microsoft.Practices.Prism.MefExtensions.MefServiceLocatorAdapter.DoGetInstance(Type serviceType, String key) in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism.MefExtensions\MefServiceLocatorAdapter.cs:line 73
   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key)
   --- End of inner exception stack trace ---
   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key)
   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance[TService]()
   at <code> line whatever...
System.ComponentModel.Composition.CompositionException: The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

person Vlad    schedule 29.08.2013    source источник


Ответы (1)


Я нашел решение, что фактическое исключение вложено глубоко в иерархию CompositionException.Errors. Можно было бы подумать, что исходное исключение будет находиться под исходным исключением композиции, но на самом деле это то, как получить к нему доступ:

Это внутреннее исключение внутри одной из ошибок другого исключения композиции, которое само по себе является одной из ошибок в исходном исключении композиции.

CompositionException compositionException = (CompositionException)activationException.InnerException;
CompositionException innerCompositionException = compositionException.Errors[0].Exception;
InvalidCastException castException = (InvalidCastException)innerCompositionException.Errors[0].Exception.InnerException

Я не буду удалять это, если кто-то еще столкнется с тем же.

person Vlad    schedule 29.08.2013
comment
Думаю, я просто столкнулся с этим. По сути, MEF начал жаловаться на повторяющиеся части, когда я внес лишь небольшое изменение в свой код. Мне потребовалось немного времени, чтобы понять, что конструктор моей части выдавал исключение... спасибо - person Aaron Anodide; 19.09.2013