Unity resolve based on class requesting instance - c#

I'm trying to set up Registrations in Unity, and I'm having trouble getting exactly what I need.
Imagine I have the following definitions:
public interface ISomeInterface { ... }
public interface ISomeDependency { ... }
public class DependencyA : ISomeDependency { ... }
public class DependencyB : ISomeDependency { ... }
public class SomeClassA : ISomeInterface
{
public SomeClassA(ISomeDependency dep){ ... }
}
public class SomeClassB : ISomeInterface
{
public SomeClassB(ISomeDependency dep){ ... }
}
I then register them with Unity as follows:
Container.RegisterType<ISomeDependency, DependencyA>("DependencyA");
Container.RegisterType<ISomeDependency, DependencyB>("DependencyB");
Container.RegisterType<ISomeInterface, SomeClassA>("ClassA");
Container.RegisterType<ISomeInterface, SomeClassB>("ClassB");
I also register a factory that will build an ISomeInterface based off a key.
Container.RegisterType<Func<string, ISomeInterface>(new InjectionFactory(c=>
{
return new Func<string, ISomeInterface>(x=>
{
return c.Resolve<ISomeInterface>(x)
}
}));
(incidentally, if anyone knows a better way of creating keyed factories I'd welcome the tip)
How can I configure Unity such that when Unity builds me an instance of SomeClassA, it will also inject an instance of DependencyA? The same when Unity builds me an instance of SomeClassB, it will inject an instance of DependencyB.
Appreciate your help.
edit: corrected my typo

If you register two concrete types for one interface, Unity will not know which one to resolve to. You'll have to provide more information. One way to do that is to use a parameter override.
// Override the constructor parameter "dep" value
// Use DependencyA instead of other value
var result = container.Resolve<ISomeInterface>(
new ParameterOverride("dep", new DependencyA())
.OnType<SomeClassA>());
But, you've also registered bot SomeClassA and SomeClassB as type of ISomeInteface, so you'll also have to tell Unity which one of those implementations you want when you want an ISomeInterface.

Related

Factory pattern: Restrict object construction to factory

I have a class T and a factory TFactory that creates objects of type T.
I want to make sure that only the factory is allowed to create new T objects.
A halfhearted solution would be to require the factory as a parameter in T's constructor, for the only purpose that only somebody who at least brings a factory object can create T's:
class T
{
public T(TFactory Tf)
{
if (!(Tf is TFactory))
throw new InvalidOperationException("No factory provided");
}
}
But wherever a TFactory is at hand, one could construct T's.
Another approach would be to check via stack tracing, if the constructor call really came from within a TFactory, but this seems overkill to me.
A third apporach would be to put both T and TFactory in an assembly of their own, ad make T's constructor internal. But a new project and assembly just for this purpose?
Any better idea anybody?
(Although my code is C#, this is probably a more general question)
Here's something very similar to your third approach: declare the factory as a inner class of T, and make T's constructor private:
public class T {
public class Factory {
public T GetT() {
return new T(); // simple implementation just for an example here
}
}
private T() {}
}
Since Factory is inside T, it can access the private constructor, but outside code cannot. If you don't want to create a separate assembly, you could consider this approach.
Note that you could still put the factory class and T in two different files, with partial classes:
public partial class T {
private T() {}
// other stuff about T here...
}
// in another file
public partial class T {
public class Factory {
public T GetT() {
return new T();
}
// other stuff about Factory here...
}
}
public abstract class T { }
public class TFactory
{
public T CreateT() => new TImpl();
private class TImpl : T { }
}
The second approach is the worst one. That behavior is absolutely unobvious and unclear to a client. Stack tracing also slows down execution. The 1st and the 2nd make sense.
If you want to have total control of instance creation put it into the type. Use a factory method. Remember, one should be reasonable when putting constraint on instance creation. E.g. the instance should be initiated with a polymorphal (virtual) method. One can't call such a method from a constructor (a very bad practice), so the method should be called after construction. For not to put that responsibility on the client, hide the constructor from one and provide a factory method.
abstract class Base
{
protected abstract void Initialize();
}
class Derived : Base
{
protected Derived() { /* ... */}
protected override void Initialize() { /* ... */}
public Derived CreateDerived()
{
var derived = new Derived();
derived.Initialize();
return derived;
}
}

C# - Returning an implementation when generic method type is an Interface

This is how I want to use it:
var fooStuff = _foo.DoBarStuff().GetFooStuff(id);
I'd like to return the implementation when DoBarStuff() is called so that I can call GetFooStuff(id) to get fooStuff.
public interface IFoo() : IBar
{
FooStuff GetFooStuff(int id);
}
public class Foo
{
public FooStuff GetFooStuff(int id)
{
// get fooStuff
return fooStuff;
}
}
public interface IBar
{
T DoBarStuff<T>();
}
public class Bar
{
public T DoBarStuff<T>()
{
// do bar stuff
return T;
}
}
The T is any interface and when 'return T;' is executed I need it's implementation returned. As it is now, I get this error under T on 'return T;' line.
T is a type, which is not valid in the given context. Type parameter
name is not valid at this point.
Thanks!
This should work:
public interface IBar
{
T DoBarStuff<T>() where T : class, new();
}
public class Bar : IBar
{
public T DoBarStuff<T>() where T : class, new()
{
// do bar stuff
return new T();
}
}
But you will have to specify the type when using the method DoBarStuff:
Usage: var fooStuff = _foo.DoBarStuff<FooWhatEver>().GetFooStuff(id)
If you don't want to, make your class/interface generics:
public interface IBar<T> where T : class, new()
{
T DoBarStuff<T>();
}
public class Bar<T> : IBar<T> where T : class, new()
{
public T DoBarStuff()
{
// do bar stuff
return new T();
}
}
Usage:
IBar bar = new Bar<FooWhatEver>();
var fooStuff = _foo.DoBarStuff().GetFooStuff(id);
But all of this doesn't work for interface, only instantiable classes (with a default constructor).
For interfaces, you will need something to make the conversion between them and theirs implementations.
The simple way is to use a dictionary (for the testing purpose, but you can use dependency injection framework as #N_tro_P suggested, even if choosing between one of them, now, shouldn't be your main goal).
You will end up with something like this (don't forget your inheritance and the generic part):
public class Bar // <T> or not depending on your choice
// You can add this constraint to avoid value types (as int):
// where T : class
{
Dictionary<Type, Type> _container = new Dictionary<Type, Type>();
{
{typeof(IFoo), typeof(Foo)}
};
public T DoBarStuff() // <T> or not depending on your choice
// You can add this constraint to avoid value types (as int):
// where T : class
{
// get fooStuff
return Activator.CreateInstance(_container[typeof(T)]);
// You will get an error if T is not in the container
// or if _container[typeof(T)] is not instantiable
// or doesn't have a default constructor.
}
}
The only problem is, you will have to fill the dictionary/container with all your interfaces/classes you want to use, it can become pretty annoying to deal with.
You might want prefer to use one of my first solutions instead.
You can do this but not how you wrote your calling signature.
You never had your Bar not use IBar and Foo use it as an interface. So you should change that. You may be confusing how to interact with interfaces.
Adjusted Code
public interface IFoo
{
FooStuff GetFooStuff(int id);
}
public class Foo : IFoo
{
public FooStuff GetFooStuff(int id)
{
// get fooStuff
return fooStuff;
}
}
public interface IBar
{
T DoBarStuff<T>();
}
public class Bar : IBar
{
public T DoBarStuff<T>()
{
// do bar stuff
return container[typeof(T)];
}
}
The usage of what you are asking is to ensure you put the type in then, such as this.
var fooStuff = _foo.DoBarStuff<BarStuff>().GetFooStuff(id);
This is how dependency containers work. They store with in it a Dictionary an instantiated object using the type as a key. i.e.
Dictionary instances;
Then you can also have factories stored elsewhere, but that requires your signitures match or you just assume they have independent access to their dependencies, so you would have
Dictionary> factories;
In general though, I would take a look at dependency containers. Whatever you are working on may simply be calling for it as a pattern and there are many already made so no need to roll your own. If you are wanting to return objects by type, that is a dependency container.
Also, I would recommend injecting that through so you are not coupled to an container. In other words, wrap it in an interface and then use an off the shelf one (Unity, MEF, etc.)
public interface IDependencyContainer
{
T Resolve<T>();
void Register<T>(T instance);
void Register<T>(Func<T> instance);
}

Object creation using Unity Application Block

I'm currently reading up on the Microsoft Unity Application Block in order to use it in one of my personal project. I have read a couple of articles and tutorials about it, but I have a question about it.
In this example about the framework, they use Unity in order to create an object that inherits the IVehicle interface. Those 3 classes that do inherit from it don't have any properties that have to be initialized in the constructor, so everything works well.
Obviously, in my project, this won't always be the case. I'll have some classes that do need property (or field) initialization in the constructor. My question is, how would I achieve that? Or is that something Unity can't do by itself; I would have to create the object using Unity's Resolve() function that would give me an object with uninitialized fields/properties, and then I would have to call the setter one by one on each fields/properties?
Unity supports auto-wiring which allows you to resolve complex object graphs and not just individual objects.
For example, let´s say that you have a class Car implementing ICar that depends on another class IEngine using constructor injection (Car´s constructor requires a parameter of type IEngine).
public interface ICar
{
void Accelerate();
}
public interface IEngine
{
void Accelerate();
}
public class Car: ICar
{
private readonly IEngine _engine;
public Car(IEngine engine)
{
_engine = engine;
}
public void Accelerate()
{
_engine.Accelerate();
}
}
public class Engine: IEngine
{
public Engine()
{
}
public string Message {get; set;}
public void Accelerate()
{
Console.WriteLine("Accelerating." + Message);
}
}
You will then register in Unity how to resolve ICar and IEngine:
var _container = new UnityContainer()
.RegisterType<ICar,Car>()
.RegisterType<IEngine,Engine>(
new InjectionProperty("Message", "Hello world"));
Then when you resolve ICar Unity will be able to provide an instance of Engine to the Car constructor, auto-wiring the dependency that Car has on IEngine. This is also true for any additional dependencies that Car or Engine may have and any properties registered for injection.
var car = _container.Resolve<Car>();
car.Accelerate();
Accelerating.Hello world
This way by resolving an ICar Unity will give you the full object graph needed. You can try the sample in this fiddle
EDIT
You can register a type to be resolved using a lambda method that will be executed at runtime, for example:
public interface IFoo
{
DateTime ResolvedTime {get; set;}
}
public class Foo: IFoo
{
public DateTime ResolvedTime {get; set;}
}
//Can be registered using a lambda as in:
container.RegisterType<IFoo,Foo>(
new InjectionFactory(c => new Foo{ ResolvedTime = DateTime.Now }));
You can get some info on the msdn. I have also updated the fiddle above with this lambda example.

Auto-wiring property injection

I am trying to use property injection for StructureMap in a plug-in style system.
ObjectFactory.Initialize(o => o.Scan(s =>
{
s.AssembliesFromPath("path_to_assemblies");
s.WithDefaultConventions();
});
Here is a sample implementation (purposely did not go deeper in defining T and TU as they are just simple classes)
public interface IBarService
{
void Baz();
}
public class BarService : IBarService
{
public void Baz() { /* implementation */ }
}
public abstract class PluginBase<T, TU> : IPlugin
where T : AClass, new()
where TU : BClass
{
protected PluginBase()
{
//some init code in the constructor
}
}
//Foo is created at run-time via Activator.CreateInstance()
public class FooPlugin : PluginBase<AClass, BClass>
{
[SetterProperty]
public IBarService BarService { get; set; }
public void Fooey()
{
BarService.Baz();
}
}
I want to auto-wire the property dependencies on all of these plug-ins that are created at run-time. I thought I'd start out with property injection and then move things to the constructor if the need arose.
If I do:
var obj = ObjectFactory.GetInstance<IBarService>();
anywhere in an instance of FooPlugin, I get the correct implementation and all is well.
If I do:
this.BarService.Baz();
I get a null reference exception because no instance of IBarService was set.
After I create my plug-in, if I do this:
ObjectFactory.BuildUp(pluginObject).
All is well and FooPlugin has the correct implementation of IBarService.
Is there any way to simply allow me to decorate my plugin properties with [SetterProperty] and have StructureMap automatically inject those when the Plugin is created without having to call ObjectFactory.BuildUp(pluginObject) ?
How are you creating your plugin instance in the cases where it doesn't work? Are you just doing new FooPlugin()?
If you do var plugin = ObjectFactory.GetInstance<PluginBase<AClass, BClass>>();, do you get the plugin with all the correct dependencies resolved?
If you are instantiating the object with "new", the container has no way to know that the instance needs dependencies resolved--it has no knowledge of that instance. Instances that need injected dependencies must be "managed by the container" so to speak.
You'll save yourself a lot of trouble if you just go the opposite route and inject all dependencies in the contstructor(s). This way there is a single place where you need to check if your objects are initialized properly...

StructureMap - Register Generic Type

I have the following code:
public class Dispatcher : IDispatcher {
public void Send(Order order) {
var type = typeof(IOrderHandler<>).MakeGenericType(order.GetType());
var handler = ObjectFactory.GetInstance(type);
}
}
NOTE: I am trying to get the IOrderHandler where order in this case is:
public class CoffeOrder : Order { }
My StructureMap configuration is the following:
ObjectFactory.Initialize(x => {
x.For<IOrderHandler>().Use<OrderHandler>();
});
When I debug it I get the following error:
{"StructureMap configuration failures:\r\nError: 104\r\nSource: Registry: StructureMap.Configuration.DSL.Registry, StructureMap, Version=2.6.4.0, ...
I tried other options but I always end up with a 104 error or a 202 error:
"StructureMap Exception Code: 202\nNo Default Instance defined for PluginFamily Proj.Test.Tests+IOrderHandler`1[[Proj.Test.Tests+CoffeOrder, Proj.Test, ...
NOTE: CoffeOrder is the type of the Order I am passing on my test.
My code for a Handler class and interface is the following:
public class CoffeHandler : OrderHandler<CoffeOrder> {
public override void Handle(CoffeOrder order) {
// Some Code
} // CoffeHandler
}
public interface IOrderHandler {
void Handle(Order order);
} // IOrderHandler
public interface IOrderHandler<TOrder> : IOrderHandler where TOrder : Order {
void Handle(TOrder order);
} // IOrderHandler
public abstract class OrderHandler : IOrderHandler {
public abstract void Handle(Order order);
} // OrderHandler
public abstract class OrderHandler<TOrder> : OrderHandler, IOrderHandler<TOrder> where TOrder : Order {
public override void Handle(Order order) {
TOrder torder = (TOrder)order;
Handle(torder);
} // Handle
public abstract void Handle(TOrder order);
} // OrderHandler
Could someone, please, help me out?
Thank You,
Miguel
Note that you are failing right away at registration and not at resolution. Your registration says: "When a class of type IOrderHandler is requested, return a concrete instance of OrderHandler
Your OrderHandler is an abstract class, so StructureMap cannot create a concrete instance of it. If you register as below,
ObjectFactory.Initialize(
x => x.For<IOrderHandler<CoffeOrder>>().Use<CoffeHandler>());
You are saying, "When a class of type IOrderHandler<CoffeOrder> is requested (which is what you are requesting in your example), return a concrete instance of CoffeHandler. That is a a valid mapping because it can instantiate a CoffeHandler.
While the above addressed your problem, I have a hunch you may be wanting StructureMap to do more of the leg work for you if you have lots of different implementations you want to register. If that is the case, you are in luck because StructureMap has support for Open Generics.
Then your resolution code will be like:
var handler = ObjectFactory.ForGenericType(typeof(IOrderHandler<>))
.WithParameters(order.GetType())
.GetInstanceAs<IOrderHandler>();
If you had a concrete generic implementation of IOrderHandler<> you could just register that. But since you do not and [as-per my hunch] you are not wanting to register every concrete instance, you will need to do a scan. How to do that is really a different question which I cannot answer without knowing what you want to scan. But you can see here for a blog post detailing Structure Map open generics which includes a samples covering scanning.

Categories