How can I change the composition in MEF after composition?

I installed my application to have an open security service ( ISecurityService ), which has a single IPrincipal GetPrincipal() method. Contractors are free to decide how to get the principal (through entering the domain, database, etc.). Thus, my application has parts that do things at startup, determined by the roles the user is in, for one example, I have imported the interface sections like this:

 [Import] public ISecurityService SecurityService { get; set; } [ImportMany] public IEnumerable<ISectionPanel> ImportedPanels { get; set; } public ObservableCollection<ISectionPanel> Panels { get; set; } public void OnImportsSatisfied() { Panels.Clear(); IPrincipal p = Thread.CurrentPrincipal; foreach (ISectionPanel sp in ImportedPanels.Where(sp => sp.RequiredRole == null || p.IsInRole(sp.RequiredRole))) { Panels.Add(p); } } 

Do not focus too much on the implementation, it will be later changed to annotations, however the important thing that made me crop the gutser was that the composition of the parts occurred PRIOR for the security principal that was established. This means that I now have a situation with a cat and a mouse.

Now I solved this using Lazy<T> for the import, which affected the chain, but if another part developer forgets to use Lazy<T> , it can cause the load chain and cause the application to crash.

What did others use to overcome such scenarios?

I used to have a unity, which I controlled more manually, just using RegisterInstance<T>(T t) , I am now trying to write applications using the "official" MEF, since this is related to the framework, and I no longer need to worry about unity.

Ideally, what I would like to do is.

  • Creating Parts Manually at Startup Layout
  • Create a composition container by manually adding my pre-created parts (e.g. RegisterInstance<T>(T t) in unity
  • Find the remaining parts using the usual composition methods shown in the documents.
+4
source share
2 answers

You can initialize your application in two steps:

 public static void Main(string[] args) { using (var container = new CompositionContainer(...)) { // phase 1: compose security service and initialize principal var securityService = container.GetExportedValue<ISecurityService>(); securityService.InitializePrincipal(); // phase 2: compose the rest of the application and start it var form = container.GetExportedvalue<MainForm>(); Application.Run(form); } } 
+4
source

In MEF, what more or less corresponds to RegisterInstance will be AddExportedValue . This will work if the host created the security service without using MEF. Since you still want to open the security service using MEF, something like Wim offers probably a good solution.

+2
source

Source: https://habr.com/ru/post/1347886/


All Articles