Note that there are some explanatory texts on larger screens.

plurals
  1. POStructureMap: differences between explicit vs scanned registrations
    primarykey
    data
    text
    <p>I have a situation where I want custom code to be able to override existing registrations. For example I have an interface,</p> <pre><code>public interface IInterface{ int Num {get;set;} </code></pre> <p>That by default resolves to,</p> <pre><code>public class CoreClass: IInterface{...} </code></pre> <p>(NB. this registration is done by SMs Scan() functionality (WithDefaultConventions, SingleImplementationsOfInterface)</p> <p>Now I want a piece of custom code to join SMs Initialize process and override the existing IInterface registration with its own implementation,</p> <pre><code>public class CustomClass: IInterface {...} </code></pre> <p>Here's the issue. If I do this registration by also doing a Scan() on my custom assembly and using same SM conventions as above (WithDefaultConventions, SingleImplementationsOfInterface) then at runtime when I do a GetInstance I get the exception, </p> <pre><code>No Default Instance defined for PluginFamily IInterface </code></pre> <p>But when I add the overriding registration by using,</p> <pre><code>x.For&lt;IInterface&gt;().Use&lt;CustomClass&gt;() </code></pre> <p>It all works.</p> <p>Also, when I interrogate the container using,</p> <pre><code>ObjectFactory.WhatDoIHave() </code></pre> <p>Then I get slightly different results depending on the method of registration. WhatDoIHave() basically shows you for a PLUGINTYPE which things are registered. The Name column shows the concrete types registered. When I Scan() and there are multiple implementations then I see the .Net type name of the concrete types found. But when I use the For&lt;>() method I see the multiple implementations as above but also a GUID next to the concrete type used in the For&lt;>() statement (I'm assuming this is indicating the default registration?)</p> <p>Now a lot of SO posts indicate that last registration wins (which is the behaviour I want) but what I want to know is if that only applies to explicit registrations (i.e. using For&lt;>). When I Scan() can I assume that SM is acting in a more "non-deterministic" way and not guaranteeing the last found implementation wins or am I missing something?</p> <p>Thanks &amp; sorry for the lengthy post!</p> <p>Edit: [Sample registration code as requested]</p> <pre><code> ObjectFactory.Initialize(x =&gt; { x.AddRegistry&lt;CoreRegistry&gt;(); x.AddRegistry&lt;ClientRegistry&gt;(); }); public class CoreRegistry : Registry { public CoreRegistry() { //Presentation Scan(x =&gt; { x.AssemblyContainingType&lt;SomeCoreType&gt;(); x.WithDefaultConventions(); x.SingleImplementationsOfInterface(); x.AddAllTypesOf&lt;ConfigurableEntityViewModel&gt;(); }); // Domain Scan(x =&gt; { x.AssemblyContainingType&lt;AnotherCoreType&gt;(); x.WithDefaultConventions(); x.SingleImplementationsOfInterface(); }); ... } public class ClientRegistry : Registry { public ClientRegistry() { //Presentation Scan(x =&gt; { x.AssemblyContainingType&lt;SomeClientType&gt;(); x.WithDefaultConventions(); x.SingleImplementationsOfInterface(); }); } } </code></pre> <p>So I was hoping that concrete implementations (e.g. of IInterface) from ClientRegistry would be registered last in the container and would therefore be the "default" registration and in turn be returned when calling GetInstance(). But this is not the case, it throws an error as described above.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload