One of our most valuable tests is the one asserting that Structuremap configuration is valid. Typically it looks something like this:
public void Configure_RegistryIsSetUp_RegistryShouldBeValid()
IContainer container = new Container();
//use reflection to find all axternal classes with [ServiceConfiguration] attribute and stick them to the container
//Method under test:
… where the test is there to make sure that all the For().Use() code in StructureMapConfiguration.Configure is valid. This works very well until we inject an IContentRepository or an IContentLoader in an inplementation class. This I have solved by using reflection and scanning for [ServiceConfiguration] attributes in external (EPiServer) assemblies, and adding this to the structuremap container. By example we then find that there is a DefaultContentLoader registered for IContentLoader and a DefaultContentRepository for IContentRepository. Now, after upgrading til EPiServer 8.2, the DefaultContentLoader and DefaultContentRepository classes no longer has a [ServiceConfiguration] attribute, so we can no longer automatically scan for implementations. The setup, it seems to me, is now moved to the EPiServer.Initialization.CmsCoreInitialization.ConfigureContainer() method. So now I have to do mocking like For().Use(new Mock().Object) and For().Use(new Mock().Object) before I can assert that my own structuremap configuration is valid.
Is this a new pattern by EPiServer to move structuremap configuration away from using attributes and into init-modules? It makes my test setup a bit ugly if I have to know about all external injection, while I actually only want to test my own structuremap setup.
I realize this is a bit on the technical deep end of things, but I hope to get some answers, even if it's Friday.
-- Regards,Tarjei Olsen
Usally we use the attribute when appropriate.
However at some times we want more control than the attribute can give, e.g. to control constructor arguments etc. So at those times we register the abstractions against structure map directly.
In the specified case with IContentLoader and IContentRepository the reason we do not use the attribute is that we actually have two abstractions interface IContentLoader and abstract class ContentLoader. We do however want both of these abstraction to refer to the same object instance. We could have solved it using the attribute by specifying a FactoryMethod, but then we would need to expose such a factory method, to avoid that we decided to go against structuremap directly in that case.