Is it possible to configure Ninject so that it automatically binds a type of interface to a concrete type based on the class naming conventions? I'm using Ninject version 3.
For example I have a lot of repositories in my domain layer named ITypeRepository which are implemented in my infrastructure layer as ProviderTypeRepository.
Below is an example of how I'm currently binding these is Ninject's CreateKernal method.
kernel.Bind<IClientRepository>().To<ProviderClientRepository>();
kernel.Bind<IVacancyRepository>().To<ProviderVacancyRepository>();
kernel.Bind<ICandidateRepository>().To<ProviderCandidateRepository>();
...etc etc
What I'd like is to somehow map this in one pass so that whenever I add a new repository I don't need to manually bind it.
You're looking for the Ninject Conventions Extension which can do something like:
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses().EndingWith("MySuffix")
.BindAllInterfaces();
Related
If you add a service that can work with several models using .NET Core's Dependency Injection, how do you prevent getting an error from the DI service registration not having any knowledge of your models?
For example:
private static void ConfigureServices(ServiceCollection services)
{
// is used by the three registered services below
services.AddScoped(typeof(IDataFileReader<>),
typeof(DataFileReader<>));
// but when these services get new'd up each needs to 'inform'
// the generic from above the model to work with
services.AddScoped<BankruptcyCalculator>();
// for example the above Calculator needs to be able to work with
// a Bankruptcy model and List<Bankruptcy>
services.AddScoped<LossMitigationCalculator>();
// LossMitigation model and List<LossMitgation>
services.AddScoped<PaymentCalculator>();
// Payment model and List<Payment>
}
I'm sure there is a second piece to this puzzle that I am missing. I'm new DI and DI in a .NET Core console project. You are not forced to always go down a Repository-style pattern that hides the generic in an interface behind a non-generic class, right? That is what I was kinda doing with IDataFileReader / DataFileReader. I have 20 models in total on this part of the project... don't really want to do 20 repo-style classes if I don't have to.
note: the models are tied to how I deserialize some CSV files, and are used as read-only from those files.
So I am working on API and using Ninject for DI & IoC. I know how the basic code works using Ninject but in the constructor of one of the classes an object of Logger is being sent. Rather than send it in constructor design item I would like to pass it in NinjectWebCommon.cs file.
public GAMonthlyAPIController() : this(new GAMonthlySQLReader(new NullLogger()))
This is the constructor.
kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
This is the entry in NinjectWebCommon.cs I would like to bind it in NinjectWebCommon.cs rather than default value. How would I pass that? I don't even know what to search for, so I could find answers.
The most practical way to apply the dependency injection pattern is to use constructor injection. This means that the classes GaMonthlyAPIController depend on should be passed in through the constructor, rather than hard-coded inside of the controller.
public class GAMonthlyAPIController
{
private readonly IGAMonthlySQLReader gaMonthlySqlReader;
public GAMonthlyAPIController(IGAMonthlySQLReader gaMonthlySqlReader)
{
this.gaMonthlySqlReader = gaMontlySqlReader
?? throw new ArgumentNullException(nameof(gaMontlySqlReader));
}
// implementation of controller...
}
This should be the only constructor for your controller class. The controller itself doesn't know anything about GAMontlySqlReader or any of its dependencies.
The same goes for GAMonthlySQLReader - it will allow any ILogger implementation to be injected through the constructor.
The idea is that it puts the composition root of the application in charge of how the dependencies are composed together, meaning you can easily switch them around later without making any changes to the components that you are composing. So, Ninject would be used inside of your composition root to map types to their abstraction, and then will build object graphs of all of those dependencies composed together.
kernel.Bind<ILogger>().To<MyLoggerClass>();
kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
For each of the application services, you would allow Ninject to instantiate them (so it can supply the dependencies) rather than using the new keyword inside of your application (new can be used for DTOs and Models, though).
I think you need to add Ninject.Web.WebApi using nuget to your Web Api project. Then use Ninject for creating ApiControllers:
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
And add the Bind() for GAMonthlyAPIController. No need to create a default constructor for your controller.
Have a look to this post:
http://nodogmablog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/
I have read various articles about IoC, DIP, DI and Service Locators but I'm a bit confused which is which because some articles have too vague examples and some other articles have just some specific examples without mentioning other cases.
Could you please clear this up for me, looking at the examples below and shortly explaining which examples match which pattern?
manually passing interface to constructor:
class Consumer
{
public Consumer(IStore store){...}
}
...
Consumer c = new Consumer(new ConcreteStore());
the same as the first example but using some 3rd party library (Unity, Windsor, Ninject)
the same as the first example but using BaseStore class instead of IStore interface
passing dependency to some other method, not to constructor:
class Consumer
{
public BySomething(IStore store){...}
}
...
Consumer c = new Consumer();
c.BySomething(new ConcreteStore());
passing dependencies masked inside of some other interface (bonus for this solution - when some other things are invented in the "world" and Consumer wishes to use them, we don't have to change constructor argument but just update IWorld; and we can completely replace entire World with something else when testing):
interface IWorld
{
IDictionary<string,IStore> Stores { get; set; }
IDictionary<string,ICityMap> Maps { get; set; }
...
}
class Consumer
{
public Consumer(IWorld world){...}
public BySomething(string store, string city){...}
}
...
IWorld myWorld = new HeavenlyWorld();
... // adding stores, maps and whatnot
Consumer c = new Consumer(myWorld);
a sub-question: in this case, is IWorld a service locator or not exactly?
passing a call-back function or delegate (.NET Action in this case):
c.BySomething(store, city, new Action(() => {...} ));
I added this case because the article Inversion of Control states that every callback is IoC. Is it true?
Everything you listed is a form of Dependency Injection.
"Poor Man's" DI
DI using an IoC container
"Poor Man's" DI again. DI works whether you are using an interface or an abstract class.
Method Injection
I'm not sure what you're asking here. It sounds like you want to change the instance of IWorld at runtime, which might be a case for Property Injection instead of Constructor Injection. Properties are oft used for optional dependencies or those that can change. Whether you then set that dependency at run-time with a Service Locator or other means is up to you. Another thing to consider is that IWorld might just depend on context, in which case you could do a context-depdendent constructor injection, the details of which are beyond the scope of this question.
Not related to DI
Every time you pass a dependency as a constructor/method argument, that's Dependecy Injection. It can be manual, like in most of your examples, or automatic using a DI Container aka IoC Container.
Using a container means the objects using deps are constructed by the container. You could ask the container directly for that service and in that case, there's a static property or method ( think DependecyResolver in asp.net mvc) that exposes that service. In that case you're using the Service Locator pattern. IWork in your example is not a locator, it's just a dependency.
To continue with the dependency resolver example, you register all relevant types into a container, the container is build then registered as the dependency resolver. The asp.net mvc framwork then uses the resolver (the Service Locator - SL) to instantiate controllers, views and all the deps these require.
To use the SL pattern is ok as part of a framework, but it's not ok if you're using it in your app to instantiate objects, because it couples the code to the locator. Sometimes is the only solution but 99% you is just an anti-pattern.
I am implementing the builder design pattern to construct different kinds of graph objects to be displayed on a WPF UI. I am using Ninject as my IOC container. However, I am trying to find an elegant extendable solution.
I have a ChartDirector object that takes a IChartBuilder as a dependency. I also have TemperatureChartBuilder and ThresholdChartBuilder that implement IChartBuilder. I want to inject either TemperatureChartBuilder OR ThresholdChartBuilder to ChartDirector depending on an event that is fired or depending on a client call. I have illustrated my problem below in code.
// ChartDirector also depends on this
kernel.Bind<IExample>().To<Example>();
// when called in Method X...
kernel.Bind<IChartBuilder>().To<TemperatureChartBuilder>();
// when called in Method Y...
kernel.Bind<IChartBuilder>().To<ThresholdChartBuilder();
// TemperatureChartBuilder is a dependency of ChartDirector, need a way to dynamically
// allocate which binding to use.
var director = kernel.Get<ChartDirector>();
// without Ninject I would do
var director = new ChartDirector(new TemperatureChartBuilder);
// or
var director = new ChartDirector(new ThresholdChartBuilder);
EDIT:
Coupled with Gary's answer, and noting a slight edit that ChartDirector has another dependency, I now want to do something like this:
var director = kernel.Get<ChartDirector>().WithConstructorArgument(kernel.Get<IChartBuilder>("TemperatureChart"));
Is something like this possible?
If you're just planning to use service location, as in your examples, then named bindings work fine, as per Garys answer.
A better approach, however, is to use constructor injection, and use attributes. For exampl, from the ninject wiki:
Bind<IWeapon>().To<Shuriken>().Named("Strong");
Bind<IWeapon>().To<Dagger>().Named("Weak");
...
class WeakAttack {
readonly IWeapon _weapon;
public([Named("Weak")] IWeapon weakWeapon)
_weapon = weakWeapon;
}
public void Attack(string victim){
Console.WriteLine(_weapon.Hit(victim));
}
}
Based on your comment to Gary, you're (strangely enough) stumbling into territory similar to what I asked a question about a few hours ago. See Remo's answer here: Using WithConstructorArgument and creating bound type
You would use When condition to define when to create the correct instance.
I would suggest using Contextual bindings (named bindings specifically) to accomplish this. That way you can do something like:
// called on app init
kernel.Bind<IChartBuilder>().To<TemperatureChartBuilder>().Named("TempChartBuilder");
kernel.Bind<IChartBuilder>().To<ThresholdChartBuilder().Named("ThreshChartBuilder");
// method X/Y could both call method Z that grabs the correct chart director
var director = new ChartDirector(kernel.Get<IChartBuilder>("TempChartBuilder"));
Where "TempChartBuilder" could be a variable that tells ninject which binding to resolve. So rather binding on the fly you would resolve on the fly but all binding could be defined up front. Typically IOC containers are stored at the application domain level and only need to be defined once. There may be specific cases where you need to bind dynamically but those should be rare.
More info on contextual bindings: https://github.com/ninject/ninject/wiki/Contextual-Binding
I'm using Caliburn and C#, but I feel like this is a generic MVVM/DI question.
Let's say I have a view model, NoteViewModel, that is passed a model object called Note.
Here is some code:
class NoteViewModel : PropertyChangedBase
{
private readonly Note _note;
public NoteViewModel(Note note)
{
_note = note;
}
public string Title
{
get { return _note.Title; }
set { _note.Title = value; NotifyOfPropertyChange(() => Title); }
}
}
Right now this object is created by calling new() and passing a model object.
Well, that works great, but now I need to add a method that requires an imported class from my DI container.
So do I merely call ServiceLocator.Current.GetInstance() to get it? Or should I design this view model to be created via the DI container and somehow setup a way to pass a Note object?
What is the proper way to design this view model? Basically a "PerInstance" view model that requires a model object for it's use. Does Caliburn have a built-in way to do this?
Caliburn has an interface (IHaveSubject and its typed version IHaveSubject) addressing this kind of scenario: basically it allows a mean to configure the ViewModel with a "subject" after its instantiation, tipically through the container:
class NoteViewModel : PropertyChangedBase, IHasSubject<Note> {
...
}
myNoteViewModel = ... //obtain an instance
myNoteViewModel.WithSubject(new Note());
This solution also integrates well with ISubjectSpecification / Conductor
infrastructure.
Even though post-construction initialization is a simple and effective solution, you may not want (from a pure design perspective) to renounce to an explicit constructor parameter to enforce the need for a Note to istantiate the ViewModel.
In this case I think you have to leverage peculiar features of your DI container, because you may have some parameters of the constructor representing a "real" input parameter, while other may be service dependencies.
Castle Windsor, for example, has a nice feature allowing you to quickly build an explicit (typed) factory for your ViewModel; the factory method will only allow to set the "real" parameters, while all dependencies are managed by the container (see this post for an extensive description of this Windsor feature: http://kozmic.pl/archive/2009/12/24/castle-typed-factory-facility-reborn.aspx)
Can you solve it using hierarchical view models?
To me it becomes more and more clear that I need one ViewModel per View and one ViewModel per model item or collection when building larger application.
That way we can build up ViewModels hierarchically, matching the XAML hierarchy.
The required objects can be defined or injected at the top level by app's main view model then. The nested view models can then access anything the way you design it to make things reachable by them.
About Caliburn, I don't know any specific things about that framework, sorry.
I'm using the ServiceLocator also. And I also "feel dirty" in doing this. But I have resolved to use the YAGNI principle and keep this pattern until I find a compelling payback to the complexity of adding 5 IServices into my constructors, passing them up via 3-4 layers of inheritance to the base classes in which they are needed, and creating everything via the container. Of course my app is evolving, and YAGNI doesn't always last...