Ninject bind all classes implementing the same interface
Solution 1
How can i tell Ninject that i want all the classes implementing the IStartUpTask to bind to themself automatically?
First of all, let me tell you that Ninject binds all classes to themselves automatically. You do not need to do anything special for that.
Having said that, I understand that you might want the explicit binding if you want to change scope or attach names or metadata. In this case read-on.
I do not know if it is possible to do what you are after in vanilla ninject, but you can use ninject.extensions.conventions. Using this library you can write:
Kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<IStartUpTask>()
.BindToSelf());
Solution 2
you can call it explicit in your code:
...
Bind<IStartUpTask>().To<Log4NetStartUpTask>();
Bind<IStartUpTask>().To<SomeOtherStartUpTask>();
...
Use it in SomeClass
public class SomeClass
{
private readonly List<IStartUpTask> startUpTaskList;
public SomeClass(IEnumerable<IStartUpTask> startUpTaskList)
{
this.startUpTaskList = startUpTaskList;
}
foreach (var startUpTask in this.startUpTaskList)
{
...
}
}
Related videos on Youtube
Catalin
Hello, My name is Catalin and I am a full-stack developer with the primary focus on .NET. Some of the technologies I like to work with include: ASP.NET Core, AWS, Azure, MongoDB, JavaScript, RequireJS, Gulp, React, RabbitMQ, AWS SAM I like challenges, I am a strong advocate of constant refactoring and I try to avoid coding compromises as much as possible. On my spare time I like to work on my personal project, https://github.com/KissLog-net/KissLog.Sdk Some of my favorite (professional) books are: Adaptive Code via C#: Agile coding with design patterns and SOLID principles Learning JavaScript Design Patterns Pragmatic Programmer
Updated on September 16, 2022Comments
-
Catalin almost 2 years
I have an interface class:
public interface IStartUpTask { bool IsEnabled { get; } void Configure(); }
I have multimple classes implementing the same interface
One of the classes looks like this:
public class Log4NetStartUpTask : IStartUpTask { public bool IsEnabled { get { return true; } } public void Configure() { string log4netConfigFilePath = ConfigurationManager.AppSettings["log4netConfigFilePath"]; if (log4netConfigFilePath == null) throw new Exception("log4netConfigFilePath configuration is missing"); if (File.Exists(log4netConfigFilePath) == false) throw new Exception("Log4Net configuration file was not found"); log4net.Config.XmlConfigurator.Configure( new System.IO.FileInfo(log4netConfigFilePath)); } }
How can i tell Ninject that i want all the classes implementing the
IStartUpTask
to bind to themself automatically?I found an example using StructureMap which does this, but i don't know how to do it in Ninject.
Scan(x => { x.AssemblyContainingType<IStartUpTask>(); x.AddAllTypesOf<IStartUpTask>(); x.WithDefaultConventions(); });
-
Catalin over 11 yearsThe last binding won't overwrite the previous ones?
-
Andrew Savinykh over 11 years@MikroDel: so in your example, which class will be injected when there is a need for IStartUpTask interface? This looks wrong.
-
MikroDel over 11 years@RaraituL I have updated my answer to make it easier to understand
-
Andrew Savinykh over 11 years@MikroDel: that's not what he asked.
-
Catalin over 11 years@MikroDel: yes, this is getting complicated. I know you can name the bindings like
kernel.Bind<IStartUpTask>().To<Log4NetStartUpTask>().Named("log4Net");
but it adds extra functionality i don't need -
MikroDel over 11 years@RaraituL - it was my try to help you )
-
MikroDel over 11 years@RaraituL - and your qeustion "The last binding won't overwrite the previous ones?" - no you can use all the bindings
-
FNMT8L9IN82 almost 11 yearsThis sort of worked for me, but I had to do 'BindSingleInterface' and not BindToSelf. But no matter, the trick for me was the 'InheritedFrom' bits. Thanx!
-
Umar Farooq Khawaja almost 8 yearsThe key point here is that if there are multiple bindings to the same type (in this case
Log4NetStartupTask
andSomeOtherStartupTask
are being bound toIStartupTask
), then you either have to provide additional conditions to find the one unique implementation ofIStartupTask
to be injected, or inject all implementations as anIEnumerable<IStartupTask>
. Bindings don't overwrite each other. -
mivra over 7 yearsI found this solution, but it somehow "did not work" for me. It took me a while to find out why, so I'm adding it here to add more context. By default Ninject binds only public classes, you have to call
IncludingNonePublicTypes()
method if you want to bind internal classes. -
Simone over 4 yearsSame as @noocyte.