Home > Blockchain >  .NET Core Built In Dependency Injection (DI): How can I not new up Dependencies?
.NET Core Built In Dependency Injection (DI): How can I not new up Dependencies?

Time:12-24

I am currently using the .NET Core built in Dependency Injection (DI).

My application is using the Rules Engine Design Pattern.

One of my rules, has a dependency, which has a dependency. So, I have to keep on "newing up" instances of the dependencies. I feel as though there has be a better way.

Here is an example of my code.

This works but I don't like that I have to new up the DataService and the Repository.

var rules = new List<IRule>
   {
      new Rule1(),
      new Rule2(new DataService(new Repository(CnnStr))) //This is what I don't like
   };
s.AddTransient<IRulesEngine>(sp => new RulesEngine(rules));

I started setting this up:

s.AddTransient<IRepository>(sp => new Repository(CnnStr));
s.AddTransient<IDataService>(sp => sp.GetRequiredService<DataService>());

Which seem to get me a little closer to what I want. But, I have no idea how to populate the rules list with a list of instances of the rules with out having to have to new up the dependencies (DataService and Repo).

Something like this, but I know this code is not right.

var rules = new List<IRule>
   {
      s.AddTransient<IRule>(sp => sp.GetRequiredService<Rule1>())
      s.AddTransient<IRule>(sp => sp.GetRequiredService<Rule2>())
   };
s.AddTransient<IRulesEngine>(sp => new RulesEngine(rules));

Any help would be appreciated.

Thank you.

CodePudding user response:

Register dependencies, required for rules

s.AddTransient<IRepository>(sp => new Repository(CnnStr));
s.AddTransient<IDataService, DataService>(); // you don't need sp here

Then register rules. TryAddEnumerable ensures that there will be no duplicated implementations of the same interface

s.TryAddEnumerable(new[] {
  ServiceDescriptor.Transient<IRule, Rule1>();
  ServiceDescriptor.Transient<IRule, Rule2>();
});

Register rules engine

s.AddTransient<IRulesEngine, RulesEngine>();

Note that rules engine should depend on IEnumerable<IRule>

CodePudding user response:

I got this working this morning.

I used a little bit from a lot of the responses. But, the link below suggested by @Daniel A. White is what put it all together for me.

.NET Core dependency injection -> Get all implementations of an interface

And maybe I was over-complicate as @Jeremey Lakeman suggested.

Here is the changes I made in my Program.cs file:

s.AddTransient<IRepository>(sp => new Repository(CnnStr));
s.AddTransient<IDataService, DataService>();

s.AddTransient<IRule, Rule1>();
s.AddTransient<IRule, Rule2>();

s.AddTransient<IRulesEngine, RulesEngine>();

Plus the changes I made to the Rules Engine:

private readonly IEnumerable<IRule> _rules;

public RulesEngine(IEnumerable<IRule> rules)
   {
      _rules = rules;
   }

public void RunRules()
   {   
      foreach (var rule in _rules)
      {
         rule.Execute(canonical);
      }            
   }
  • Related