Ignore constructor exceptions using MEF without hacking Visual Studio when throwing an exception

I would like to create some existing code modules ( IMyDesiredType ) for loading using MEF. Modules contain basically some constructor arguments that I want to provide with MEF ( ImportingConstructor ). So far, this works great.

The problem now arises because sometimes the dependencies are not available (they are equal to zero) in the host application. Modules will throw by convention ArgumentNullException , and I don't want to change that. However, I want the MEF to miss such objects (without including them in the graph object).

  [Export(typeof(IMyDesiredType))] class MyModule : IMyDesiredType{ [ImportingConstructor] public MyModule(object aNecessaryDependency){ if(aNecessaryDependency==null) throw new ArgumentNullException(nameof(aNecessaryDependency)) } } 

To get this, I allow MEF to instantiate Lazy<IMyDesiredType> and initialize them one by one.

 foreach(var myLazy in collectionOfMefExports){ try{ myLazy.Value // do something with the value, so the object gets composed }catch(CompositionException){ // Here I get the ArgumentNullException wrapped in a CompositionException // and also can work around it. However because of the exception handling // is on the first hand in MEF, VS will break always in the throwing // constructor of the module continue; // Go to the next module after logging etc. } } 

The problem here is that I need to catch a CompositionException , and not directly an Exception (mainly ArgumentNullException ) from the module constructor. Thus, Visual-Studio breaks down on each module, because of an exception, user code is excluded. The obvious solution for this is to tell the visual studio not to break into ArgumentNullException types, but it seems very hacky to me. And elsewhere, I want VS to crash into ArgumentNullException s.

Is there any other template with which I can make MEF not add components to the graph where the dependency is declared ( [Export] ), but its value is null or is there a method of the MEF class that I can override in a derived class and catch an exception designer on the front panel?

Please leave a comment if the question is not clear, I am not a native speaker of English, and therefore, perhaps the question is verbalizing, which is a confusing litch.

+7
c # dependency-injection visual-studio-2015 mef
source share
4 answers

Unfortunately, support for what you are asking for is limited.

Visual Studio allows you to configure by type of exception whether the debugger should be interrupted. This does not help when you are trying to show / hide the same type of exception based on the execution context. However, you can get your own exception type and use it in import constructors. This will allow you to configure breaks by type of exception, but will not make any difference between the MEF composition and other code.

In addition, methods can be marked as ignored by the debugger. See This related answer. Do not stop the debugger with this THAT exception when it is thrown and caught .

Rejecting [DebuggerStepThrough] because it is considered unreliable, the first option is [DebuggerHidden] . I want to add another candidate: [DebuggerNonUserCode] . This is reproduced with the VS option "Include only my code" (see http://blog.functionalfun.net/2008/05/debuggernonusercode-suppressing.html ).

So, while [DebuggerHidden] will never break for an exception in the constructor where it was thrown, and will report it in the next user district code, [DebuggerNonUserCode] allows you to ignore or break the constructor depending on your debug VS settings. As long as "Include only my code" is set, both attributes should behave the same.

Assuming that MEF initialization is fully handled in a hidden codec debugger, for constructor calls without MEF, the debugger is interrupted when it first reaches a ring function that is not marked as hidden.

+1
source share

It sounds as if you know which components are important and which are not. you probably want to do something like wrapping the component’s initialization in an attempt to catch as you already are, and through a configuration search to decide whether this particular exception is problematic or not in the code.

Basically, you need to create rules yourself, but in any case, a failed component loading is a failure, so components that throw exceptions cannot be added to the schedule correctly, I would think.

A common approach seems to be to remove the failure component and then rebuild the graph ...

How do I return the MEF when a part changes?

...

this may help you, though in diagnosing how and what to do next ..

https://blogs.msdn.microsoft.com/dsplaisted/2010/07/13/how-to-debug-and-diagnose-mef-failures/

0
source share

I can head the wrong direction, but does it contain an abstract factory with a default implementation for raw cases?

I use this for my addiction with DI unity ... An interesting question without a doubt!

 <Export(GetType(IComponent))> Public Class DependencyResolver Implements IComponent Public Sub SetUp(registerComponent As IRegisterComponent) Implements IComponent.SetUp 'General registerComponent.RegisterType(Of IDataContextAsync, dbEcommEntities)() 'DomainLogic registerComponent.RegisterType(Of IUserDomainLogic, MfrUserDomainLogic)() 'Services registerComponent.RegisterType(Of ICompanyService, CompanyService)() End Sub End Class 

Injection Constructors - I have an MEF export to another class library with my own dependent converter. In every web application, I register components for a new application. Each part that I received from the MEF export dependency converter can then be extended by entering the constructors of my mvc controllers. In the component loader, I load the container using dll and can also extend dependencies by adding a unique.config value after the fact.

 Private Shared Sub RegisterDependencies(container As IUnityContainer) 'load services ComponentLoader.LoadContainer(container, ".\\bin", "Service.dll") 'load config 'container.LoadConfiguration() End Sub 
0
source share

MEF has already included this as a function, since MEF Preview 6 and it was called stable composition . MEF boots safely even if no dependencies are provided.

A simple solution to the problem would be to check if the value was actually created before accessing the value.

 if(myLazy.IsValueCreated) myLazy.Value // do something with the value, so the object gets composed 

Learn more about this here .

Note. If you have optional dependencies and the system can work without them, do not put the constructor argument without the Argument argument. This will make them a necessary addiction during composition.

As you already mentioned, you do not want to change the throw exception convention when the argument is null. Well, if you know that the system will work without these dependencies, then you can avoid setting this check for such dependencies.

0
source share

All Articles