We are using StructureMap 3.1.6.186 and are running into a problem with overriding a particular plugin. In our case, we have a console application which we are deploying to a remote server. The Console application has a very distant dependency on an implementation that requires some undesirable COM objects to be installed on the server. Since we know for certain that this particular dependency isn't actually used in our Console application, we are trying to override the particular implementation that is problematic (IImageManipulator) with a fake implementation I have created right in my console application main Program.cs. This would alleviate the need to install these com objects on the server and would not break the console application.
As you'll see from the code and comments below, neither the explicit registration of IImageManipulator at the bottom of the container constructor nor the injection of the mapping after the container is constructed appears to work as expected. Interestingly, when I get an instance of IImageManipulator within the console app then it gives me the desired FakeImageManipulator implementation. However, when I get an instance of IEndItemService then the underlying implementation is the other type which I don't want.
Any idea how to override all implementations of a particular interface even when there are other registries that have this interface registered? Thanks a ton!
public class FakeImageManipulator : IImageManipulator
{
public Dictionary<ImageMetaDataEnum, string> GetMetaData(Image image, params ImageMetaDataEnum[] desiredMetaData)
{
throw new NotImplementedException();
}
}
public override void ProgramLogic()
{
IContainer container = new Container(registry =>
{
registry.ForSingletonOf<ITypeResolver>().Use<StructureMapTypeResolver>();
registry.ForSingletonOf<ILogger>().Use(() => MessageLogger.GetInstance());
registry.ForSingletonOf<IConfigParser>().Use(() => ConfigParser.GetInstance());
registry.Scan(scan =>
{
scan.AssemblyContainingType<ServiceRegistry>();
scan.LookForRegistries();
});
//--hoping this would override anything that was already set in another registry
registry.For<IImageManipulator>().Use(() => new FakeImageManipulator());
});
container.Model.For<IImageManipulator>().Default.EjectAndRemove();
//--hoping this would override anything that was already set in another registry
container.Inject(typeof(IImageManipulator), new FakeImageManipulator());
//--this gets back the FakeImageManipulator as expected
IImageManipulator actualImplementation = container.TryGetInstance<IImageManipulator>();
//--the implementation of IImageManipulator created in here is NOT a FakeImageManipulator like I want, but is
// instead the instance that is registered in some down stream registry
var someOtherImplementationThatUsesAnIImageManipulatorDownStream = container.GetInstance<IEndItemsService>();
}
Edit: Also see this google group post which is the same question: https://groups.google.com/forum/#!topic/structuremap-users/RAR_0JbOVGQ
pluginGraph.For<ISomeInterface>().ClearAll().Use<FakeImplementation>()
of the parent plugin of the plugin I was trying to fake. It happens that I didn't really need the parent so this ended up being OK... but still no idea why I couldn't clear and inject the IImageManipulator dependency. – Bravissimo