Interface dependency hierarchy - c#

I currently have a main class which might call another class which might call 2 or 3 others. The main class might create a Windows form as well.
So at the moment we might have:
public class MainClass
{
...
AnotherClass = new AnotherClass();
fmMain myForm = new fmMain();
}
public class AnotherClass
{
...
DatabaseClass dbClass = new DatabaseClass();
FileClass fClass = new FileClass();
}
As I see it, after refactoring and putting in constructor interface dependencies I can use an IOC container.
The problem is my entry point is the main class so all I can see to do is have all the dependencies in the main class constructor and then pass these down into the other classes and forms.
The issue is this could get very messy and the main class might have 10 dependencies most of which used in other classes. Is there an alternative?

Let the IoC container to do this.
Register AnotherClass as a dependency and then resolve it directly referring to container instance.

Dependencies should be defined locally to where they are required i.e. the dependencies should be defined on the constructors of the types, then use an IoC container to resolve all types. In this way the IoC takes care of "passing these down into the other classes and forms". When using an IoC container avoid using "new" whenever possible, and instead use the container to create instances. It will handle creation and injection of dependencies for you.
For example (using Ninject), the following demonstrates a Form which defines its own dependencies. The container will supply and inject all dependencies recursively when used to resolve an instance of the ProductForm.
Dependencies do not need to be injected into the entry-point class, but are specified as bindings in a module and then injected by the container when types such as Forms are resolved.
public class Program
{
public Program()
{
IKernel kernel = new StandardKernel(new MainModule());
Form form = kernel.Get<ProductForm>();
form.Show();
}
}
public class MainModule : NinjectModule
{
public override void Load()
{
Bind<ProductForm>().ToSelf();
Bind<IProductService>().To<ProductService>();
Bind<IProductDb>().To<IProductDb>();
}
}
internal class ProductForm : Form
{
private readonly IProductService _productService;
public ProductForm(IProductService productService)
{
_productService = productService;
}
}
internal interface IProductService {}
internal class ProductService : IProductService
{
private readonly IProductDb _productDb;
public ProductService(IProductDb productDb)
{
_productDb = productDb;
}
}
internal interface IProductDb {}
internal class ProductDb : IProductDb {}

It sounds like your Main class is your Composition Root. That's fine - it's not going to become messy if that's the only thing it does. This should be its single responsibility. In other words: your application entry point should be a Humble Object.

Related

Inheritance - derived classes required to instantiate the base class constructor

I have lack of understanding in this basic concept of OOP. Here is an example:
Say I have a base repository which is derived by 3 different classes. The base class requires the dbContext in the constructor , injected by dependency injection. Because of this the child classes have to pass the dbContext every time I instantiate them. The requirement is simple: The base class should instantiate the Context for the child classes. Is that possible? I do not want the child classes to worry about the context. I just want them to call it.
Here is my base class.
public class CastingBaseRepository<TEntity> : ICastingBaseRepository<TEntity> where TEntity : class, IEntity
{
private readonly CastingContext _context;
public CastingBaseRepository(CastingContext context) => _context = context ?? throw new ArgumentNullException(nameof(context));
// Context property
public CastingContext Context => _context;
}
Heres how the child class would be:
public class CommercialJobsRepository : CastingBaseRepository<Audition>, ICommercialJobsRepository
{
/* I do not want to use base(context) here. I need a way for this class to just call Context property from the derived class.. Possible? */
private CastingContext _context;
public CommercialJobsRepository(CastingContext context) : base(context)
{
_context = context;
}
public async Task<IList<OpenJobs>> GetOpenJobs()
{
// test code
var tt = await _context.Audition.Take(10).ToListAsync();
return new List<OpenJobs>();
}
}
Here is my context class
public partial class CastingContext : DbContext
{
public virtual DbSet<Audition> Audition { get; set; }
public CastingContext(DbContextOptions<CastingContext> options) : base(options)
{
}
}
And here is the startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// DB Context
services.AddDbContextPool<CastingContext>(options => { options.EnableSensitiveDataLogging(); options.UseSqlServer(Configuration.GetConnectionString("dbCast")); });
}
}
I am using strategy pattern to determine which child class would be accessed at runtime. That too needs to have CastingContext injected the constructor which is again ugly. The point is, there should be only one class exposing the context to all derived classes or perhaps through a static method. Can you please help me understand how to do it?
Here is my Strategy class:
public class JobsStrategyContext
{
private readonly CastingContext _context;
private readonly Dictionary<eBreakdownTypes, IJobsRepository> Strategies =
new Dictionary<eBreakdownTypes, IJobsRepository>();
public JobsStrategyContext(CastingContext context)
{
_context = context;
Strategies.Add(eBreakdownTypes.Ftv, new FtvJobsRepository(_context));
Strategies.Add(eBreakdownTypes.Commercial, new CommercialJobsRepository(_context));
Strategies.Add(eBreakdownTypes.Theatre, new TheatreJobsRepository(_context));
}
public async Task<IList<OpenJobs>> GetOpenJobsBySubType(eBreakdownTypes breakdownType)
{
return await Strategies[breakdownType].GetOpenJobs();
}
}
No, you cannot both at the same time use dependency injection and hardcode the instantiation of your dependency in the base class. If you want to inject the dependency from an external consumer, it needs to pass through the derived constructor.
At best, you can pass a service locator which the base constructor then uses to fetch the dbcontext, but then you're still handling the service locator in the derived class. But service locators are no longer considered good practice because they have notable drawbacks such as decreasing readability/usability and becoming a general nuisance to handle in sufficiently large codebases.
While it would technically achieve what you want to achieve, don't start using static service locators. The costs far outweigh the benefits.
However, the problem outset doesn't quite make sense to me. If you're using dependency injection, I would assume you're using some sort of automated injection where you don't have to manually instantiate all dependencies.
Yes, you still need to mention the dbcontext as a (derived and base) constructor parameter, but your derived classes don't need to handle it (other than passing it to the base constructor. The effort to do so is minimal and it allows for maximum freedom in terms of dependency injection.
This is how inheritance works by design.
This is a functional limitation of C# as a language. You don't have to provide the same constructor(s) in child classes as you have in the base class, but you must satisfy those constructors in the base class. For example:
public class BaseClass
{
public BaseClass(Dependency dep) {}
}
public class ChildClass
{
public ChildClass(Dependency dep) : base(dep) {}
}
Or:
public class ChildClass
{
public ChildClass() : base(new Dependency()) {}
}
In either case, you somehow, someway must provide the Dependency instance to the base class constructor, but you may opt to not actually construct the child class with that dependency, and instead, get it internally.
However, in practical terms with something like DbContext which relies itself on dependencies being injected, it's going to require carrying that dependency all the way through: your child class will need a constructor where it can be injected in order to then pass down into the base class constructor.
You have to provide the dependency through the child class because, When you are creating an instance of the child class, the base class is also getting constructed and hence the dependencies must be supplied.
Of course for the ease of coding and managing these dependencies,you can use Use the IoC containers like Unity to handle the automatic dependency injections (The Unity Application dependency injection container with support for constructor, property, and method call injection)

IoC and the Factory Pattern

If I understand the Factory Pattern correctly, I might have a factory for creating my Repos that implements an interface like this ...
public interface IRepoFactory
{
T Get<T>() where T : IRepo
}
And in that factory a call to RepoFactory.Get<IRepo1>() will return a newly minted instance of a class implementing IRepo1.
So, in the definition of RepoFactory I will create a new instance of the appropriate type...
switch(...)
{
case typeof(IRepo1):
return new Repo1();
}
Or, I assume, I can define a constructor for Repofactory that takes, as parameters, an interface representing all of the possible return types...
public RepoFactory(IRepo1 repo1, IRepo2 repo2, ..., IRepoN repoN) : IRepoFactory
and let my IoC container do the work of creating the classes.
So, to my question. If I do create a constructor as above, doesn't that mean that each time I include IRepoFactory as a constructor parameter I will get a new instance of Repo1, Repo2,..., RepoN? Is that a resource heavy process? Is it a wasteful way to do things if, in any given case, I will likely need only a subset of the total number of available repos?
Is there a way of getting the IoC (Unity, in my case) to only create an instance at the time it is needed, a Lazy Loading, if you will? Or am I simply worrying about nothing?
You misunderstood Factory. Factory should create instances. That's mean nothing should be in factory constructor beside of Di container or LifeTimeScope.
You can use your own factory or you can use auto generated factory.
I'm not familiar Unity but I checked they have.
public class MyService : IMyService
{
private readonly Func<IRepo1> _repo1;
public MyService(Func<IRepo1> repo1)
{
_repo1 = repo1;
}
public void Method1()
{
var myRepo = _repo1();
}
public void Method2()
{
//Repo1 instance will be different than in Method1
var myRepo = _repo1();
}
}
If you have a container then you can let the container resolve the type of repo when needed.
Here is a rough example of how you can do it. Note you will change the code to suit you specific container and also the assumption here is that you would have also already configured the container to know hot to resolve the types you want.
public class DefaultRepoFactory : IRepoFactory {
IUnityContainer container;
public DefaultRepoFactory(IUnityContainer container) {
this.container = container;
}
public T Get<T>() where T : IRepo {
return (T)container.Resolve<T>();
}
}
Configuration
IUnityContainer myContainer = new UnityContainer();
IRepoFactory myDefaultFactory = new DefaultRepoFactory(myContainer);
myContainer.RegisterInstance<IRepoFactory>(myDefaultFactory);

Do I pass singletons as parameters or do I manually resolve them? (Unity DI)

I am using unity mvc4 package, it is auto injecting into my controllers fine. But now I am manually doing other parts of my application, helpers etc.
How can I access the singletons within the container from other classes?
How do I call MethodWithDependency(param) on my instance of MyClass2? Am I supposed to do the below? It looks far too messy.
public class MyClass1
{
public void Main()
{
var myObject2 = container.Resolve<MyClass2>;
var someObject = container.Resolve<SomeClass>;
myObject2.MethodWithDependency(someObject);
}
}
public class MyClass2
{
public void MethodWithDependency(SomeClass someObject)
{
}
}
Each object that needs its dependencies resolved can potentially have them resolved by the container. To not to spoil your code with containers, you create local factories and implement specific factory providers elsewhere, in the Composition Root which is the only place in your application where container is created and used directly.
This requires discipline, however you are able to structure your code so that there is no explicit reference to the container except for the Composition Root and still container does the job.
I wrote a tutorial on that once, it is too long to quote it here:
http://www.wiktorzychla.com/2012/12/di-factories-and-composition-root.html
Answering your specific question: to have singletons you just use the ContainerControllerLifetimeManager as the parameter to the register method.
http://msdn.microsoft.com/en-us/library/ff660872(v=pandp.20).aspx
Create MyClass2 so that it accepts SomeClass as an argument in the constructor (you are injecting the SomeClass dependency into your MyClass2 object).
Then, you can register your Instances with the Container. At that point, when you resolve your MyClass2 object, your SomeClass object will also be resolved and injected into MyClass2.
Beautiful, huh?
The Code
public class MyClass1
{
private UnityContainer _container;
public void Main()
{
this.RegisterContainer();
// Since SomeClass was registered, when you resolve MyClass2, it will
// magically resolve an instance of SomeClass that the MyClass2
// constructor needs.
var myObject2 = this._container.Resolve<MyClass2>;
myObject2.MethodWithDependency();
}
private void RegisterContainer()
{
// Here, initialize your Container then register your singletons.
this._container = new UnityContainer();
// Do not use container.RegisterType<>()....
// RegisterInstance, by default, implements a singleton behavior.
this._container.RegisterInstance<SomeClass>();
this._container.RegisterInstance<MyClass2>();
}
}
public class MyClass2
{
private SomeClass _someClass;
// You are injecting the SomeClass dependency into your MyClass2 class.
// Hence the name — Dependency Injection.
public MyClass2(SomeClass someClass)
{
this._someClass = someClass;
}
public void MethodWithDependency()
{
// use your _someClass object.
this._someClass.DoSomething();
}
}

Unity Static Property Injection

I have two classes, one which sets up the container by registering types and one which contains a static property which I want to inject into. My issue is the property is never set by injection so when I call a method on it, the property is always null.
public class ClassOne
{
public void Method()
{
Container.RegisterType<IClass, ClassImplOne>("ImplOne");
Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
}
}
public static class ClassTwo
{
[Dependency]
public static IClass SomeProperty { get; set; }
public static void SomeOtherMethod()
{
SomeProperty.AnotherMethod();
}
}
If I remove the Dependency attribute and in ClassOne do a simple
ClassTwo.SomeProperty = Container.Resolve<IClass>("ImplOne");
it works fine, but I want to know if it is possible to do this without explicitly assigning a value to the property (i.e. can the container inject through attributes)?
Edit:
Thanks. I have removed the static declaration from ClassTwo and in ClassOne added RegisterType and Resolve for ClassTwo and also added InjectionProperty:
Container.RegisterType<IClass, ClassImplOne>("ImplOne", new InjectionProperty("SomeProperty"));
but it still does not work :S
Edited after considering comments:
There are a variety of reasons why at times you still want or need to use static classes instead of cascading everything through Unity.
If the static class has a dependency on another class that you would want to be configurable/exchangeable via your Unity configuration I prefer using a factory pattern as described at How to resolve dependency in static class with Unity? or simply assigning a function to resolve the dependency when needed, rather than referencing the Container from within the static class. One advantage being that all your Unity configuration can be in the same place.
In your case it could look like this:
public static class ClassTwo
{
private static IClass _someProperty;
public static Func<IClass> ResolveProperty { private get; set; }
private static IClass SomeProperty
{
get { return _someProperty ?? (_someProperty = ResolveProperty()); }
}
public static void SomeOtherMethod()
{
SomeProperty.AnotherMethod();
}
}
And in your Unity configuration add this:
ClassTwo.ResolveProperty = () => container.Resolve<IClass>();
Unity inject dependencies when the class is resolved through Unity. A static class can not be created, so Unity can not inject dependencies.
Instead of having a Static class, use Unity to resolve a pseudo-singleton class (ContainerControlledLifetimeManager) of ClassTwo. This way Unity injects IClass to ClassTwo when ClassTwo is created (resolved throug Unity container) and, as is configured as singleton, you always have the same instace of ClassTwo in the whole lifecicle of your application.
You must resolve ClassTwo through Unity.
Container.RegisterType<IClass, ClassImplOne>("ImplOne");
Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
Container.RegisterType<InterfaceImplemetedByClassTwo, ClassTwo>();
//Simple example. Don't forget to use ContainerControlledLifetimeManager for ClassTwo to simulate sigleton.
And when you need ClassTwo:
Container.Resolve<InterfaceImplemetedByClassTwo>
Having the config in ClassTwo:
public class ClassTwo : InterfaceImplemetedByClassTwo
{
[Dependency("ImplOne")] //inject ClassImplOne
public IClass SomeProperty { get; set; }
BUT this is not a great solution, I think your problem is with the phylosophy of DI. You need to cascade dependencies from the top layer classes of your app. Resolve the top layer classes in a explicit way. (Container.Resolve) and dependecies injection cascade down thanks to the magic of Unity. When 2 classes (top layer or not) need to use the same instance of ClassTwo Unity do the dirty work if you configured ClassTwo with ContainerControlledLifetimeManager.
In other words, you don't need static class, you inject the same instance of a class in other classes than need it.

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...

Categories