How to use dependency injection in a method or property? - c#

Normally I use Dependency injection in the constructor of a class.
The dependencies are registered in the unity container, f.e.:
container.RegisterType<IMyInterface, MyClass>();
But in one class it is not possible to inject with the constructor (it's a third party class which I inherit from and the default constructor (without injection) MUST be used.
How can I use my MyClass in this class too?
Thanks!

If the main constraint is calling the default constructor of the 3rd party class, can't you do something like this?
public class InheritedClass : ThirdPartyClass
{
private IMyInterface _myInterface;
// the default ctr of the 3rd party class is still being called
public InheritedClass(IMyInterface myInterface, string arg) : base(arg)
{
_myInterface = myInterface;
}
}
In case you actually mean your own inherited class has a certain constructor that you have to use, then why not do something like this ?
public class InheritedClass : ThirdPartyClass
{
// Constructor that has to be used
public InheritedClass(string arg) : base(arg)
{
}
// Ctr with DI that also calls the required default ctr - could be used instead..
public InheritedClass(IMyInterface myInterface, string arg) : this(arg)
{
_myInterface = myInterface;
}
}
In case none of these apply to your case, what you're looking for is the concept of Method Injection, an example could be this one

I guess I don't understand how this is hard.
(it's a third party class which I inherit from and the default constructor (without injection)
Assume this is a 3rd Party Class that you inherit from:
public abstract MyClassBase
{
public MyClassBase()
{
}
public abstract void DoSomething();
}
What prevents you from deriving and injecting?
public MyClassDerived
{
private IInjectioned _injection;
public MyClassDerived(IInjectioned injection)
// Call default constructor without params
: base()
{
_injection = injection;
}
public override void DoSomething()
{
_injection.DoSomething();
}
}

Related

Unity: tell container to always use specific implementation of an interface when registering a type

I keep running into this scenario: suppose I have interface IFoo and several implementations, like RedFoo : IFoo and BlackFoo : IFoo. I then have classes that take IFoo in the constructor:
class BlackFooUser
{
public BlackFooUser(IFoo foo, other_parameters_here) {...}
}
class RedFooUser
{
public RedFooUser(IFoo foo, other_parameters_here) {...}
}
How do I tell the container to resolve all other parameters as usual, but always use BlackFoo when constructing BlackFooUser, and always use RedFoo when constructing RedFooUser? I know I can use ParameterOverride when calling Resolve(), but I want it to be the same whenever a Red/BlackFooUser is resolved, so this should go into RegisterType or RegisterFactory.
I can do something like
container.RegisterFactory<RedFooUser>(c=>new RedFooUser(c.Resolve<RedFoo>(), other_parameters_here));
but this is quite verbose, and this will have to change every time I add new parameters.
Is there a better way?
UPDATE I am specifically looking to do this through container registrations, without modifying the classes involved. There are multiple reasons for that, but it boils down to this:
Encoding dependency information in the classes violates separation of concerns
It usually scales poorly in case of many classes and many dependencies
It puts limits to how the classes can be composed
It restricts me to classes that I own the source to and can modify at will
Use an abstract class and generics to force a specific type.
Unity will automatically resolve a concrete type, so you don't need to register these.
public abstract class FooUser<TFoo> where TFoo : IFoo
{
private readonly TFoo _foo;
public FooUser(TFoo foo, other parameters)
{
_foo = foo;
}
}
public class BlackFooUser : FooUser<BlackFoo>
{
public BlackFooUser (BlackFoo foo, other parameters)
: base(foo, other parameters)
{
}
}
public class RedFooUser : FooUser<RedFoo>
{
public RedFooUser (RedFoo foo, other parameters)
: base(foo, other parameters)
{
}
}
Full reproduction below - output is:
Constructed RedFooUser with foo 'RedFoo' and otherParameter 'I'm the other parameter'
Constructed BlackFooUser with foo 'BlackFoo' and otherParameter 'I'm the other parameter'
void Main()
{
var container = new UnityContainer()
.RegisterInstance<string>("I'm the other parameter");
var foo1 = container.Resolve<RedFooUser>();
var foo2 = container.Resolve<BlackFooUser>();
}
// Define other methods, classes and n
public interface IFoo
{
}
public class BlackFoo : IFoo { }
public class RedFoo : IFoo { }
public abstract class FooUser<TFoo> where TFoo : IFoo
{
private readonly TFoo _foo;
public FooUser(TFoo foo, string otherParameter)
{
_foo = foo;
Console.WriteLine($"Constructed {GetType().Name} with foo '{foo.GetType().Name}' and otherParameter '{otherParameter}'");
}
}
public class BlackFooUser : FooUser<BlackFoo>
{
public BlackFooUser(BlackFoo foo, string otherParameter)
: base(foo, otherParameter)
{
}
}
public class RedFooUser : FooUser<RedFoo>
{
public RedFooUser(RedFoo foo, string otherParameter)
: base(foo, otherParameter)
{
}
}
When you register your types, you can give them a name, and then refer to that name in the constructors where those types get injected. Something like this:
public class BlackFoo : IFoo
{
public const string UNITY_KEY = "BlackFoo";
}
In your container registration:
_container.RegisterType<IFoo, BlackFoo>(BlackFoo.UNITY_KEY, new ContainerControlledLifetimeManager());
In your constructor:
public class BlackFooUser
{
public BlackFooUser([Dependency(BlackFoo.UNITY_KEY)] IFoo foo)
{
}
}
This ensures that when the container does the dependency injection, it will use the named IFoo registration.
I submitted an issue to UnityContainer repo, and the response by Eugene Sadovoy pushed me towards this answer.
To avoid an infinite loop, one can register the default factory as named registration, and invoke it from the default, unnamed factory, along the lines of (sorry, I changed the names a little compared to the question):
container
.RegisterType<SpecialFooUser>("stdreg")
.RegisterFactory<SpecialFooUser>(
c => c.Resolve<SpecialFooUser>("stdreg",
new DependencyOverride<IFoo>(c.Resolve<SpecialFoo>()))
);
This works, but looks quite verbose, so I wrote a few extension methods and classes (~100 lines of code total) to make it less verbose and more expressive:
container.Register(
new CustomFactory<SpecialFooUser>()
.DependencyOverride<IFoo, SpecialFoo>());
The complete source code is on GitHub: https://github.com/ikriv-samples/UnityResolveOverrideFactory

Allow no default instance to be registered with StructureMap

We have an interface which is implemented by two classes:
public interface ISomething { void DoSomething(); }
public class Something1 : ISomething { public void DoSomething() {...} }
public class Something2 : ISomething { public void DoSomething() {...} }
These interfaces are used by two different modules. Module1 needs Something1 and Module2 needs Something2:
public class Module1(ISomething something) { something.DoSomething(); }
public class Module2(ISomething something) { something.DoSomething(); }
We set this up in a registry:
For<Module1>().Use<Module1>().Ctor<ISomething>().Is<Something1>();
For<Module2>().Use<Module2>().Ctor<ISomething>().Is<Something2>();
However, when it runs, we get the following error:
No default Instance is registered and cannot be automatically determined for type 'ISomething'
If we create and register a default class, then it works and we do not get the above error:
public class DefaultSomething : ISomething { public void DoSomething() {...} }
For<ISomething>().Use<DefaultSomething>();
All the uses of the interface are configured in the registry and we do not want to have to specify a default, but it seems like you have to tell StructureMap what to use, even if it never needs to use it. Is it possible to not have to specify a default instance?
Thanks :)

c# class inherits from base class with constructor with dependency injection

I have a project using Dependency Injection (Ninject) where I have the following class:
public class SecurityService : BaseService
{
ISecurityRepository _securityRepo = null;
public SecurityService(ISecurityRepository securityRepo)
{
_securityRepo = securityRepo;
}
}
Because BaseService is going to be referenced in many other service classes I wanted to add there a method that also go to Data Repository and get some information so I don't have to repeat the same code along the other service classes.
Here is what I have for BaseRepository:
public partial class BaseService
{
IEntityRepository _entityRepo = null;
public BaseService(IEntityRepository entityRepo)
{
_entityRepo = entityRepo;
}
public Settings AppSettings
{
get
{
return _entityRepo.GetEntitySettings();
}
}
}
But when I compile I get the following error:
There is no argument given that corresponds to the required formal parameter 'entityRepo' of 'BaseService.BaseService(IEntityRepository)'
And the error make sense because now I have a constructor that I guess is expecting something.
Any clue how to fix this but that I can still have my dependency injection in BaseRepository class?
UPDATE
I just tried to remove the constructor and use the attribute [Inject] but when debugging I see that _entityRepo is NULL.
Add the dependency to the constructor for the derived class, and pass it along.
public SecurityService(ISecurityRepository securityRepo, IEntityRepository entityRepo)
: base(entityRepo)
{
_securityRepo = securityRepo;
}
I could make it work:
I just convert the private property to be public and then [Inject] attribute started to work.
public partial class BaseService
{
[Inject]
public IEntityRepository EntityRepo { get; set; }
}
Pass the Repository object to the base class via the child class constructor:
public SecurityService(ISecurityRepository securityRepo) : base(IEntityRepository)
{
//Initialize stuff for the child class
}

Force derived class to implement base class constructor with parameter(s)

Is it possible to enforce a compile-time contract on derived classes requiring implementation of a constructor (with parameter)?
I have a base class with a constructor requiring a parameter:
public class FooBase
{
protected int value;
public FooBase(int value) { this.value = value; }
public virtual void DoSomething() { throw new NotImplementedException(); }
}
I'd like to force derivations of my base class to implement the same constructor:
public class Foo : FooBase
{
public Foo(int value) : base(value) { }
public override void DoSomething() { Console.WriteLine("Foo: {0}", value); }
}
If no constructor is implemented, derived classes causes a compiler error because there is no default constructor in the base class:
// ERROR: 'Does not contain a constructor that takes 0 arguments'
// Adding default constructor in FooBase eliminates this compiler error, but
// provides a means to instantiate the class without initializing the int value.
public class FooBar : FooBase
{
public override void DoSomething() { Console.WriteLine("FooBar: {0}", value); }
}
Adding a default constructor, FooBar(), in the derived class silences the compiler error, but provides a dangerous means of instantiating FooBar without the required base class int value being initialized. Because I'm using a factory (see below), silencing the compiler error only results in a run-time error later. I'd like to force FooBar to implement FooBar(int)
INTERESTING OBSERVATION:
If a default constructor, FooBase(), is added to FooBase, then it is 'inherited' by derived classes that do not provide a constructor:
Foo does not inherit the default constructor because it supplies an explicit constructor.
FooBar DOES inherit FooBase().
HOWEVER, the same is not true with the non-default constructor FooBase(int)!
Foo MUST explicitly implement FooBase(int) and call base(int).
FooBar FAILS to 'inherit' the non-default constructor the same way that a default constructor is inherited!
I do not want a default constructor in the base class because instances are created using a factory method that supplies a needed "settings" parameter. That factory method is not illustrated here (which uses the Activator.CreateInstance() method).
Here is the way derived classes should be instantiated:
static void Main(string[] args)
{
FooBase myFoo = new Foo(4); // Works, since Foo(int) is implemented.
// ERROR: 'Does not contain a constructor that takes 1 arguments'
FooBase myFooBar = new FooBar(9); // Fails to compile.
}
Because I am using a factory--not direct instantiation as shown--there is no compiler error. Instead, I get a runtime exception: 'Constructor on type not found.'
Unworkable solutions:
Interfaces do not support constructors.
Constructors cannot be virtual or abstract.
It appears that supplying a base class cannot enforce a contract on constructors.
Work-around:
Provide a default constructor in base class along with property to pass settings parameter.
If a default constructor, FooBase(),
is added to FooBase, then it is
'inherited' by derived classes that do
not provide a constructor:
This is incorrect - constructors in general are never inherited. A default constructor is automatically provided for a class that does not provide any other constructor implementation.
You could put in a constraint on an interface that provides an Init() method for you:
public interface IInit
{
void Init(int someValue);
}
public class FooBase : IInit
{
..
}
Did you try
public class FooBase
{
protected int value;
private FooBase(){}
public FooBase(int value) { this.value = value; }
public virtual void DoSomething() { throw new NotImplementedException(); }
}
the private constructor prevents the option of parameter-less constructor
If you provide just the constructor with a parameter on the base class, the derived class has to call that when it is constructed. This doesn't however force it how it should be called. It could be called with some default value, or the value could be computed from other constructor parameters.
Constructors are not inherited. What happens instead is that when you don't specify any constructors in a class (structs act differently), a public parameterless constructor is created, that calls the parameterless constructor of the base class. Of course, this won't happen if the base class doesn't have such constructor, in which case you have to specify the constructor yourself.
As #BrokenGlass mentions, the only way to force such a constraint is to have an abstract method Init() on the base class (possibly from an interface). I think that in general, such practice is not good OOP-design (object should be usable after creation, without the need to call other methods), but in this case it might be the best solution.
It seems either that I don't understand what you mean or what you mean is wrong.
Having the following, causes compiler error:
public class FooBase
{
protected int value;
public FooBase(int value) { this.value = value; }
public virtual void DoSomething() { throw new NotImplementedException(); }
}
public class Foo : FooBase
{
public Foo(int value) : base(value) { }
public override void DoSomething() { Console.WriteLine("Foo: {0}", value); }
}
public class FooBar : FooBase
{
public FooBar() // <----------------- HERE telling 'Test.FooBase' does not contain a constructor that takes 0 arguments
{
}
public override void DoSomething() { Console.WriteLine("FooBar: {0}", value); }
}
So it is safe. But if you try to do the following
public class FooBase
{
protected int value;
public FooBase() {} // <------------ LOOK HERE
public FooBase(int value) { this.value = value; }
public virtual void DoSomething() { throw new NotImplementedException(); }
}
public class Foo : FooBase
{
public Foo(int value) : base(value) { }
public override void DoSomething() { Console.WriteLine("Foo: {0}", value); }
}
public class FooBar : FooBase
{
public FooBar() // <----------------- No error here
{
}
public override void DoSomething() { Console.WriteLine("FooBar: {0}", value); }
}
And if it is wrong to declare ctor in FooBase then it's your responsibility as a developer not to do so...
As others have noted, an interface method such as Init() is a bit awkward. An interface should expose behavior, not internal requirements. The internal state of your object helps implement that behavior. A class is generally a way to wrap up state and behavior. The constructor exposes the internal requirements, but the consumer of the interface's "service" doesn't care about this; they only care about the behavior:
interface IFoo
{
void DoSomething();
}
So it's natural that different implementations will require different constructors because they often require different internal state to implement IFoo.DoSomething.
The problem that you're running into then is how to write general-purpose code that knows how to instantiate all of these different types. Factory methods and variations on Activator.CreateInstance are commonly used to accomplish this in an ad hoc manner. I'd encourage looking at a couple of alternatives that solve this more elegantly:
IoC/DI containers are generally a better approach because they standardize these techniques, perform better, and bring a lot of additional capabilities.
In .NET 4, the Managed Extensibility Framework (MEF, a.k.a. System.ComponentModel.Composition) has an overlapping set of capabilities with a lot of the same benefits, especially suited for plugin designs.

How can I prevent a base constructor from being called by an inheritor in C#?

I've got a (poorly written) base class that I want to wrap in a proxy object. The base class resembles the following:
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
public BaseClass(int someValue) {}
//...more code, not important here
}
and, my proxy resembles:
public BaseClassProxy : BaseClass
{
public BaseClassProxy(bool fakeOut){}
}
Without the "fakeOut" constructor, the base constructor is expected to be called. However, with it, I expected it to not be called. Either way, I either need a way to not call any base class constructors, or some other way to effectively proxy this (evil) class.
There is a way to create an object without calling any instance constructors.
Before you proceed, be very sure you want to do it this way. 99% of the time this is the wrong solution.
This is how you do it:
FormatterServices.GetUninitializedObject(typeof(MyClass));
Call it in place of the object's constructor. It will create and return you an instance without calling any constructors or field initializers.
When you deserialize an object in WCF, it uses this method to create the object. When this happens, constructors and even field initializers are not run.
If you do not explicitly call any constructor in the base class, the parameterless constructor will be called implicitly. There's no way around it, you cannot instantiate a class without a constructor being called.
At least 1 ctor has to be called. The only way around it I see is containment. Have the class inside or referencing the other class.
I don't believe you can get around calling the constructor. But you could do something like this:
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
protected virtual void Setup()
{
}
}
public BaseClassProxy : BaseClass
{
bool _fakeOut;
protected BaseClassProxy(bool fakeOut)
{
_fakeOut = fakeOut;
Setup();
}
public override void Setup()
{
if(_fakeOut)
{
base.Setup();
}
//Your other constructor code
}
}
If what you want is to not call either of the two base class constructors, this cannot be done.
C# class constructors must call base class constructors. If you don't call one explicitly, base( ) is implied. In your example, if you do not specify which base class constructor to call, it is the same as:
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base() { }
}
If you prefer to use the other base class constructor, you can use:
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base(someIntValue) { }
}
Either way, one of the two will be called, explicitly or implicitly.
When you create a BaseClassProxy object it NEEDS to create a instance of it's base class, so you need to call the base class constructor, what you can doo is choose wich one to call, like:
public BaseClassProxy (bool fakeOut) : base (10) {}
To call the second constructor instead of the first one
I am affraid that not base calling constructor isn't option.
I ended up doing something like this:
public class BaseClassProxy : BaseClass
{
public BaseClass BaseClass { get; private set; }
public virtual int MethodINeedToOverride(){}
public virtual string PropertyINeedToOverride() { get; protected set; }
}
This got me around some of the bad practices of the base class.
constructors are public by nature. do not use a constructor and use another for construction and make it private.so you would create an instance with no paramtersand call that function for constructing your object instance.
All right, here is an ugly solution to the problem of one class inheriting the constructors of another class that I didn't want to allow some of them to work. I was hoping to avoid using this in my class but here it is:
Here is my class constructor:
public MyClass();
{
throw new Exception("Error: Must call constructor with parameters.");
}
OK now you were warned that it was ugly. No complaints please!
I wanted to force at least the minimal parameters from my main constructor without it allowing the inherited base constructor with no parameters.
I also believe that if you create a constructor and do not put the : base() after it that it will not call the base class constructor. And if you create constructors for all of the ones in the base class and provide the same exact parameters for them in the main class, that it will not pass through. But this can be tedious if you have a lot of constructors in the base class!
It is possible to create an object without calling the parameterless constructor (see answer above). But I use code like this to create a base class and an inherited class, in which I can choose whether to execute the base class's init.
public class MyClass_Base
{
public MyClass_Base()
{
/// Don't call the InitClass() when the object is inherited
/// !!! CAUTION: The inherited constructor must call InitClass() itself when init is needed !!!
if (this.GetType().IsSubclassOf(typeof(MyClass_Base)) == false)
{
this.InitClass();
}
}
protected void InitClass()
{
// The init stuff
}
}
public class MyClass : MyClass_Base
{
public MyClass(bool callBaseClassInit)
{
if(callBaseClassInit == true)
base.InitClass();
}
}
Here is my solution to the problem
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(new Child().Test);
}
public class Child : Parent {
public Child() : base(false) {
//No Parent Constructor called
}
}
public class Parent {
public int Test {get;set;}
public Parent()
{
Test = 5;
}
public Parent(bool NoBase){
//Don't do anything
}
}
}
A simple elegant solution. You can change it according to your need.
Another simple solution from me:
class parent
{
public parent()
{
//code for all children
if (this.GetType() == typeof(child1))
{
//code only for objects of class "child1"
}
else
{
//code for objects of other child classes
}
}
}
class child1 : parent
{
public child1()
{}
}
// class child2: parent ... child3 : parent ... e.t.c

Categories

Resources