Unity Registration: Hooking up an interface to a pre-registered concrete class - inversion-of-control

I already have a concrete class registered in my unity container and I want to, later on, register an interface that hooks up to that class but uses the existing registration.
I can do this using the following code but it causes a resolve at registration time...
container.RegisterInstance<IMyClass>(container.Resolve<MyClass>());
Is it possible to hook the code up with all resolution done at the point the interface is resolved?

The trick is to use an InjectionFactory:
container.Register<IMyClass>(
new InjectionFactory(c => c.Resolve<MyClass>()));

It sounds like you want to create a factory type. Here, a Func delegate type is used to avoid the creation of a new custom factory type:
container.RegisterInstance<Func<IMyClass>>(() => container.Resolve<MyClass>());
Your other types can then take a dependency on this factory:
private IMyClass myClass;
public MyOtherType(Func<IMyClass> myClassFactory)
{
this.myClass = myClassFactory();
}

IUnityContainer container = new UnityContainer();
var onlyInstance = new MyClass();
container.RegisterInstance<IMyClass>(onlyInstance);
IMyClass resolved = container.Resolve<IMyClass>();
if (object.ReferenceEquals(onlyInstance, resolved))
{
Console.WriteLine("Equal");
}
This prints "Equal". This is the way I would register the instance in the first place.
In a comment above, you imply that you do not control the initial registration. That's the real issue. I would recommend going down one of the following paths (in order of preference, highest to lowest):
Create your own UnityContainer independent of the pre-registered one
Create a child container with CreateChildContainer
Use named (non-default) mappings

Related

Use dependency injection with specific instance - MS Unity

I'm writing MVVM application which based on PRISM.
I learning PRISM in those days and I have a technical question about UnityContainer.
Is there any way to inject specific instance while I using container.Resolve?
I will try to explain by example.
Lets register the next types:
var container = new UnityContainer();
container
.RegisterType(typeof(ISomeClass), typeof(SomeClass))
// with string
container
.RegisterType(typeof(IExample), typeof(Example), "SpecificExampleInstance")
// without string
container
.RegisterType(typeof(IExample), typeof(Example));
The constructor of SomeClass get IExample as input parameter.
Now I want resolve instance of SomeClass but tell to "container" to inject into SomeClass constructor the instance of IExample - "SpecificExampleInstance" (the one which registered at line 3 in the code above) and not the IExample - without string (the one which registerd at line 4 of above code - without string)
I'm hoaping that my question clear enough, If not please let me know and I will try to change the formulation.
Thanks
One option is to use the Dependency attribute:
public class SomeClass
{
public SomeClass([Dependency("SpecificExampleInstance")] IExample myExample)
{
// work with the service here
}
}

StructureMap IoC problem getting the instance in runtime

i have 2 concrete types "CategoryFilter" & "StopWordsFilter" that implements
"IWordTokensFilter".
Below is my setup:
ForRequestedType<IWordTokensFilter>().TheDefaultIsConcreteType<CategoryFilter>()
.AddInstances(x =>
{
x.OfConcreteType<StopWordsFilter>();
}
);
The problem is the run-time when structure map auto inject it on my class, bec. i have arguments with same plugin-type:
public ClassA(IWordTokensFilter stopWordsFilter, IWordTokensFilter categoryFilter)
i'm always getting CategoryFilter in my first argument but it should be stopWordsFilter.
How can i setup this in a right way? thanks in advance
There are a number of possible solutions:
1) Does ClassA need to differentiate between the filters, or does it just need to run them both? If not, you can change the constructor to accept an array, which will cause all registered instances of IWordTokensFilter to be injected:
public ClassA(IWordTokensFilter[] filters)
You can then foreach over the filters to apply them.
2) If you do need to differentiate them, because they need to be used differently, you may consider having one implement a marker interface the better describes its purpose. ClassA could then be changed to take in an IWordTokensFilter and an ICategoryFilter (or whatever you name the marker interface). Register CategoryFilter with ICategoryFilter and then both will be injected properly.
public ClassA(IWordTokensFilter stopWordsFilter, ICategoryFilter categoryFilter)
3) You can tell StructureMap explicitly how to create ClassA:
ForRequestedType<ClassA>().TheDefault.Is.ConstructedBy(c => {
return new ClassA(c.GetInstance<StopWordsFilter>(), c.GetInstance<CategoryFilter>());
});
4) You can tell StructureMap to override one of the dependencies for ClassA:
x.ForRequestedType<ClassA>().TheDefault.Is.OfConcreteType<ClassA>()
.CtorDependency<IWordTokensFilter>("stopWordsFilter").Is<StopWordsFilter>();

How to carry out custom initialisation with autofac

I'm adding autofac to an existing project and some of the service implementations require their Initialize method to be called and passed configuration information. Currently I'm using the code:
builder.Register(context =>
{
var service =
new SqlTaxRateProvider(context.Resolve<IUserProvider>());
service.Initialize(config);
return service;
}
).As<ITaxService>()
.SingleInstance();
which works but I'm still creating the object myself which is what I'm trying to get away from this and allow autofac to handle it for me. Is it possible to configure a post create operation that would carry out the custom initialisation?
To give you an idea of what I'm after ideally this would be the code:
builder.RegisterType<SqlTaxRateProvider>()
.As<ITaxService>()
.OnCreated(service=> service.Initialize(config))
.SingleInstance();
Update:
I am using Autofac-2.1.10.754-NET35
.OnActivating(e => e.Instance.Initialize(...))
should do the trick.
You might also investigate the Startable module (see the Startable entry in the Autofac wiki).
Mark's suggestion to do initialisation in the constructor is also a good one. In that case use
.WithParameter(new NamedParameter("config", config))
to merge the config parameter in with the other constructor dependencies.

Resolving constructor paramters using the same name used for resolving the object

Say I have this class
public class MyObject : IObject
{
public MyObject(IObject2 object2)
{
}
}
which I resolve like:
Container.Resolve<IObject>("SomeName");
Is it possible to configure Unity so that whenever an IObject is resolved using any name, then the IObject2 will also be resolved with that same name (assuming it was registered with such a name)?
I'm looking for a way that doesn't use InjectionConstructor, as I son't want to update it for every new name I introduce.
This ought to work:
container.RegisterType<IObject2, MyObject2>("someName");
// ...
container.RegisterType<IObject, MyObject>("someName",
new InjectionConstructor(
new ResolvedParameter<IObject2>("someName")));
If you want to register more names, you could always consider packaging this little snippet into a reusable method that takes the name as an input parameter.
I don't have Unity nearby right now, so this is more or less from memory...

Class design: file conversion logic and class design

This is pretty basic, but sort of a generic issue so I want to hear what people's thoughts are. I have a situation where I need to take an existing MSI file and update it with a few standard modifications and spit out a new MSI file (duplication of old file with changes).
I started writing this with a few public methods and a basic input path for the original MSI. The thing is, for this to work properly, a strict path of calls has to be followed from the caller:
var custom = CustomPackage(sourcemsipath);
custom.Duplicate(targetmsipath);
custom.Upgrade();
custom.Save();
custom.WriteSmsXmlFile(targetxmlpath);
Would it be better to put all the conversion logic as part of the constructor instead of making them available as public methods? (in order to avoid having the caller have to know what the "proper order" is):
var custom = CustomPackage(sourcemsipath, targetmsipath); // saves converted msi
custom.WriteSmsXmlFile(targetxmlpath); // saves optional xml for sms
The constructor would then directly duplicate the MSI file, upgrade it and save it to the target location. The "WriteSmsXmlFile is still a public method since it is not always required.
Personally I don't like to have the constructor actually "do stuff" - I prefer to be able to call public methods, but it seems wrong to assume that the caller should know the proper order of calls?
An alternative would be to duplicate the file first, and then pass the duplicated file to the constructor - but it seems better to have the class do this on its own.
Maybe I got it all backwards and need two classes instead: SourcePackage, TargetPackage and pass the SourcePackage into the constructor of the TargetPackage?
I'd go with your first thought: put all of the conversion logic into one place. No reason to expose that sequence to users.
Incidentally, I agree with you about not putting actions into a constructor. I'd probably not do this in the constructor, and instead do it in a separate converter method, but that's personal taste.
It may be just me, but the thought of a constructor doing all these things makes me shiver. But why not provide a static method, which does all this:
public class CustomPackage
{
private CustomPackage(String sourcePath)
{
...
}
public static CustomPackage Create(String sourcePath, String targetPath)
{
var custom = CustomPackage(sourcePath);
custom.Duplicate(targetPath);
custom.Upgrade();
custom.Save();
return custom;
}
}
The actual advantage of this method is, that you won't have to give out an instance of CustomPackage unless the conversion process actually succeeded (safe of the optional parts).
Edit In C#, this factory method can even be used (by using delegates) as a "true" factory according to the Factory Pattern:
public interface ICustomizedPackage
{
...
}
public class CustomPackage: ICustomizedPackage
{
...
}
public class Consumer
{
public delegate ICustomizedPackage Factory(String,String);
private Factory factory;
public Consumer(Factory factory)
{
this.factory = factory;
}
private ICustomizedPackage CreatePackage()
{
return factory.Invoke(..., ...);
}
...
}
and later:
new Consumer(CustomPackage.Create);
You're right to think that the constructor shouldn't do any more work than to simply initialize the object.
Sounds to me like what you need is a Convert(targetmsipath) function that wraps the calls to Duplicate, Upgrade and Save, thereby removing the need for the caller to know the correct order of operations, while at the same time keeping the logic out of the constructor.
You can also overload it to include a targetxmlpath parameter that, when supplied, also calls the WriteSmsXmlFile function. That way all the related operations are called from the same function on the caller's side and the order of operations is always correct.
In such situations I typicaly use the following design:
var task = new Task(src, dst); // required params goes to constructor
task.Progress = ProgressHandler; // optional params setup
task.Run();
I think there are service-oriented ways and object-oritented ways.
The service-oriented way would be to create series of filters that passes along an immutable data transfer object (entity).
var service1 = new Msi1Service();
var msi1 = service1.ReadFromFile(sourceMsiPath);
var service2 = new MsiCustomService();
var msi2 = service2.Convert(msi1);
service2.WriteToFile(msi2, targetMsiPath);
service2.WriteSmsXmlFile(msi2, targetXmlPath);
The object-oriented ways can use decorator pattern.
var decoratedMsi = new CustomMsiDecorator(new MsiFile(sourceMsiPath));
decoratedMsi.WriteToFile(targetMsiPath);
decoratedMsi.WriteSmsXmlFile(targetXmlPath);