Why does asp.net core support several ways for registering a service? - asp.net-mvc

I will create a service StudentData from class Student:
public interface IStudentData
{
List<Student> GetAll();
}
public class StudentData : IStudentData
{
public List<Student> GetAll()
{
var students = new List<Student>
{
new Student { FirstName = "Harry", LastName = "Potter" },
new Student { FirstName = "Hermione", LastName = "Granger" }
};
return students;
}
}
public class Student
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Here is some ways to register the service:
services.AddTransient<IStudentData, StudentData>();
services.AddTransient(typeof(IStudentData), typeof(StudentData));
services.Add(new ServiceDescriptor(typeof(IStudentData), typeof(StudentData), ServiceLifetime.Transient));
services.Add(new ServiceDescriptor(typeof(IStudentData), p => new StudentData(), ServiceLifetime.Transient));
services.AddSingleton<IStudentData, StudentData>();
services.AddSingleton(typeof(IStudentData), typeof(StudentData));
services.Add(new ServiceDescriptor(typeof(IStudentData), typeof(StudentData), ServiceLifetime.Singleton));
services.Add(new ServiceDescriptor(typeof(IStudentData), p => new StudentData(), ServiceLifetime.Singleton));
services.AddScoped<IStudentData, StudentData>();
services.AddScoped(typeof(IStudentData), typeof(StudentData));
services.Add(new ServiceDescriptor(typeof(IStudentData), typeof(StudentData), ServiceLifetime.Scoped));
services.Add(new ServiceDescriptor(typeof(IStudentData), p => new StudentData(), ServiceLifetime.Scoped));
services.AddInstance<IStudentData>(new StudentData());
services.AddInstance(typeof(IStudentData), new StudentData());
services.Add(new ServiceDescriptor(typeof(IStudentData), new StudentData()));
So, when to use the first/second/thirth...?
Sub-question: Is there another way to register a service?

The reason that there are multiple ways of configuring the same thing is simply for convenience and to make it flexible and descriptive to the extent of the C# language.
// These are the same, you're just specifying the types and the lifetime:
services.AddTransient<IStudentData, StudentData>();
services.AddTransient(typeof(IStudentData), typeof(StudentData));
In the above declarations, it is descriptive and convenient to simply provide the interface type and the concrete service implementation type - but it is achievable through the C# language in multiple ways. The first making use of generic type parameters, the second constructor parameters.
The following declarations are also the same, as they are currently written, but are made more flexible because the Add method accepts a ServiceDescriptor object, which has even more overloads for added flexibility.
// These are doing the same thing, they just configure the resolution of the interface to a bog standard instance of the StudentData class.
services.Add(new ServiceDescriptor(typeof(IStudentData), typeof(StudentData), ServiceLifetime.Transient));
services.Add(new ServiceDescriptor(typeof(IStudentData), p => new StudentData(), ServiceLifetime.Transient));
I'll take the last example that you gave (immediately above) and explain a simple use case to show the flexibility of it:
Imagine that the class StudentData accepts the current HttpContext as a constructor parameter (it is a dependency of the class). I could configure it so that whenever an instance of type IStudentData is resolved to StudentData, that it is resolved with the current HttpContext passed into the constructor.
// Passing in the current HttpContext into StudentData
services.Add(new ServiceDescriptor(typeof(IStudentData), p => new StudentData(HttpContext.Current), ServiceLifetime.Transient));
But it's not just limited to passing in specific values, you can provide any method that returns an instance of your class (a factory) - so the possibilities are endless (sort of).
There is no right or wrong one to choose when configuring your dependencies, but I would recommend choosing the one that makes it most clear what is being configured.

You can find more info about dependency injection here: https://docs.asp.net/en/latest/fundamentals/dependency-injection.html
For ex: Singleton, means that you will create your service once, and then, use the same instance during all application's life-cicle

A general rule of thumb is, if you know the type at compile time, use the generic version services.AddTransient<IStudentData, StudentData>();.
When you don't know the type ahead of compile time, i.e. when you iterate through the assembly via reflection and get all types which implement a certain interface, you use the non-generic version, because you can't use generics in this case.
foreach(var type in GetAllOfSomeInterface()) {
services.AddTransient(typeof(ISomeInterface), type);
}
Use the Func<IServiceProvider, T> ones when you need a factory method to resolve stuff that you can't otherwise via DI, i.e. a setting or option that's determined when the application starts and you can't use IOptions<T> (i.e. third party library where you can't change the class to accept the options DI pattern).
Use services.Add when you create your own dependency injection system and the overloads for it, or when you need to dynamically determine the scope (Transient, Scoped or Singleton), usually used when you wrap around an existing IoC container. You'll rarely use that though.

Related

ASP.NET MVC: Mocking Database on Data-driven Environment?

I am making a MSTest project of my app created with Data-driven strategy.
Now, I would like to mock the database using interface. But the DB Entity is automatically generated, so my modification for DI will be destroyed when entity was updated.
Should I give up testing with a mock and access the actual DB every time?
(Update 2022/01/28) I am thinking for compromise: rather than accessing DB entity directly on the model, I would make service facades that on the one class handles DB (for production usage), while the other just works itself.
Short crude examples here:
public interface IMemberDatabaseService
{
Member Search(string name);
void Create(MemberModel model);
}
public class MemberDatabaseService : IMemberDatabaseService, IDisposable
{
private AutomaticallyGeneratedDBContext Con = new();
public Member Search(string name)
{
return Con.Member.SingleOrDefault(mb => mb.Name == name);
}
public void Create(MemberModel model)
{
Member member = Convert(model);
Con.Member.Add(model);
Con.SaveChanges();
}
private static Member Convert(MemberModel model)
{
// convert model to Member
}
// Dispose pattern here...
}
public class MemberTestService : IMemberDatabaseService, IDisposable
{
private static List<Member> MemberList = new();
public Member Search(string name)
{
return name == "John Doe" ? new Member{ Name = name, ...} : null;
}
public void Create(MemberModel model)
{
Member member = Convert(model); // convert model to Member
MemberList.Add(model);
}
private static Member Convert(MemberModel model)
{
// convert model to Member
}
// Dispose pattern here...
}
The drawback is I cannot test the LINQ portion or conflict handling without connecting the DB.
You will need to add specific detail about what your implementation looks like.
Mocking DbContexts/DbSets is possible, but arguably a fair bit of work and ugly to work with. Unit testing is one good argument for implementing a Repository pattern to serve as a boundary for the mocks, but if you're past the point where something like that can be implemented, a simpler solution can be to point your DbContext at an in-memory database that is seeded with suitable test data.
The downside is that most test frameworks accommodate running tests in parallel and not necessarily in order so you need to ensure each test's data row dependencies are safely isolated from each other to ensure you don't get intermittent failures due to one test tampering with data that another test relies on.

Default values for constructor arguments in a library project

I am writing a library that will provide a collection of public types to its consumers.
I want to make types from this library dependency injection friendly. This means that every class needs to have a constructor through which it is possible to specify every single dependency of the object being initialized. I also want the library to adhere to the convention over configuration principle. This means that if a consumer wants the default behavior, he may use a parameterless constructor and the object will somehow construct the dependencies for itself.
In example (C#):
public class Samurai {
private readonly IWeapon _weapon;
// consumers will use this constructor most of the time
public Samurai() {
_weapon = ??? // get an instance of the default weapon somehow
}
// consumers will use this constructor if they want to explicitly
// configure dependencies for this instance
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
}
My first solution would be to use the service locator pattern.
The code would look like this:
...
public Samurai() {
_weapon = ServiceLocator.Instance.Get<IWeapon>();
}
...
I have a problem with this, though. Service locator has been flagged as an anti-pattern (link) and I completely agree with these arguments. On the other hand, Martin Fowler advocates use of the service locator pattern exactly in this situation (library projects) (link). I want to be careful and eliminate the possible necessity to rewrite the library after it shows up that service locator really was a bad idea.
So in conclusion - do you think that service locator is fine in this scenario? Should I solve my problem in a completely different way? Any thought is welcome...
If you want to make life easier for users who are not using a DI container, you can provide default instances via a dedicated Defaults class which has methods like this:
public virtual Samurai CreateDefaultSamurai()
{
return new Samurai(CreateDefaultWeapon());
}
public virtual IWeapon CreateDefaultWeapon()
{
return new Shuriken();
}
This way you don't need to pollute the classes themselves with default constructors, and your users aren't at risk of using those default constructors unintentionally.
There is an alternative, that is injecting a specific provider, let's say a WeaponProvider in your case into your class so it can do the lookup for you:
public interface IWeaponProvider
{
IWeapon GetWeapon();
}
public class Samurai
{
private readonly IWeapon _weapon;
public Samurai(IWeaponProvider provider)
{
_weapon = provider.GetWeapon();
}
}
Now you can provide a local default provider for a weapon:
public class DefaultWeaponProvider : IWeaponProvider
{
public IWeapon GetWeapon()
{
return new Sword();
}
}
And since this is a local default (as opposed to one from a different assembly, so it's not a "bastard injection"), you can use it as part of your Samurai class as well:
public class Samurai
{
private readonly IWeapon _weapon;
public Samurai() : this(new DefaultWeaponProvider())
{
}
public Samurai(IWeaponProvider provider)
{
_weapon = provider.GetWeapon();
}
}
I have used the following approach in my C# project. The goal was to achieve dependency injection (for unit / mock testing) whilst not crippling the implementation of the code for a "normal use case" (i.e. having a large amount of new()'s that are cascaded through the execution flow).
public sealed class QueueProcessor : IQueueProcessor
{
private IVbfInventory vbfInventory;
private IVbfRetryList vbfRetryList;
public QueueProcessor(IVbfInventory vbfInventory = null, IVbfRetryList vbfRetryList = null)
{
this.vbfInventory = vbfInventory ?? new VbfInventory();
this.vbfRetryList = vbfRetryList ?? new VbfRetryList();
}
}
This allows DI but also means any consumer doesn't have to worry about what the "default instance flow" should be.

Creating objects with dependencies - dependency injection

Let's say we have class:
public class WithDependencies
{
public WithDependencies(IAmDependencyOne first, IAmDependencyTwo second)
// ...
}
Now the question. How do you create objects of WithDependencies class in an application?
I know there are many ways.
new WithDependencies(new DependencyOne(), new DependencyTwo());
new WithDependencies(IoC.Resolve(IDependencyOne), IoC.Resolve(IDependencyTwo());
// register IDependencyOne, IDependencyTwo implementations at app start
IoC.Resolve(WithDependencies);
// register IDependencyOne, IDependencyTwo implementations at app start
// isolate ourselves from concrete IoC Container
MyCustomWithDependenciesFactory.Create();
and so on...
What do you think is the way to do it?
Edit:
Because I don't get answers or I don't understand them I'll try to ask again. Let's say that on some event (button, timer, whatever) I need new object WithDependencies(). How do I create it? Assume IoC container is already configured.
It depends on the context, so it's impossible to provide a single answer. Conceptually you'd be doing something like this from the Composition Root:
var wd = new WithDependencies(new DependencyOne(), new DependencyTwo());
However, even in the absence of a DI Container, the above code isn't always unambiguously the correct answer. In some cases, you might want to share the same dependency among several consumers, like this:
var dep1 = new DependencyOne();
var wd = new WithDependencies(dep1, new DependencyTwo());
var another = AnotherWithDependencies(dep1, new DependencyThree());
In other cases, you might not want to share dependencies, in which case the first option is more correct.
This is just a small glimpse of an entire dimension of DI concerned with Lifetime Management. Many DI Containers can take care of that for you, which is one excellent argument to prefer a DI Container over Poor Man's DI.
Once you start using a DI Container, you should follow the Register Resolve Release pattern when resolving types, letting Auto-wiring take care of the actual composition:
var wd = container.Resolve<WithDependencies>();
The above example assumes that the container is already correctly configured.
If you need to create a dependency which has its own dependencies, you can either A) do it yourself, or B) ask something else to do it for you. Option A negates the benefits of dependency injection (decoupling, etc.), so I would say option B is a better starting point. Now, we have chosen to use the factory pattern, no matter whether it takes the form of a service locator (i.e. IoC.Resolve), a static factory, or an instance factory. The point is that we have delegated that responsibility to an external authority.
There are a number of trade-offs required for static accessors. (I went over them in another answer, so I won't repeat them here.) In order to avoid introducing a dependency on the infrastructure or the container, a solid option is to accept a factory for creating WithDependencies when we need an instance somewhere else:
public class NeedsWithDependencies
{
private readonly IWithDependenciesFactory _withDependenciesFactory;
public NeedsWithDependencies(IWithDependenciesFactory withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo()
{
var withDependencies = _withDependenciesFactory.Create();
...Use the instance...
}
}
Next, we can create a container-specific implementation of the factory:
public class WithDependenciesFactory : IWithDependenciesFactory
{
private readonly IContainer _container;
public WithDependenciesFactory(IContainer container)
{
_container = container
}
public WithDependencies Create()
{
return _container.Resolve<WithDependencies>();
}
}
Now NeedsWithDependencies is completely isolated from any knowledge of how WithDependencies gets created; it also exposes all its dependencies in its constructor, instead of hiding dependencies on static accessors, making it easy to reuse and test.
Defining all those factories can get a little cumbersome, though. I like Autofac's factory relationship type, which will detect parameters of the form Func<TDependency> and automatically inject a function which serves the same purpose as the hand-coded factory above:
public class NeedsWithDependencies
{
private readonly Func<WithDependencies> _withDependenciesFactory;
public NeedsWithDependencies(Func<WithDependencies> withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo()
{
var withDependencies = _withDependenciesFactory();
...Use the instance...
}
}
It also works great with runtime parameters:
public class NeedsWithDependencies
{
private readonly Func<int, WithDependencies> _withDependenciesFactory;
public NeedsWithDependencies(Func<int, WithDependencies> withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo(int x)
{
var withDependencies = _withDependenciesFactory(x);
...Use the instance...
}
}
Sometimes I try to get rid of factories or at least not depend directly on them, so Dependency Injection (without factories) is useful of course.
Therefore I use Google Juice, cause its a small little framework using Java Annotations and you can quickly change your injections / dependencies. Just take a look at it:
http://code.google.com/p/google-guice/

Ninject 2.0: Property Injection without attribute

Is there a way to use Property Injection in Ninject 2 without using the [Inject] attribute? This creates a dependency to Ninject in the class that will be wired using it and I prefer to avoid having unneeded dependencies to my IoC container, that's why I end up using Constructor Injection more often.
I guess the same applies to Method Injection
I followed Ruben's tip and posted a small blog post on how to achieve this, but here's the quick answer:
Create a custom attribute:
public class InjectHereAttribute : Attribute
{
}
The target class will now look like this:
public class Samurai
{
[InjectHere]
public IWeapon Context { get; set; }
}
Now Ninject must be configured to use the custom attribute, this can be done by creating an implementation of IInjectionHeuristic that recognizes the custom attribute:
public class CustomInjectionHeuristic : NinjectComponent, IInjectionHeuristic, INinjectComponent, IDisposable
{
public new bool ShouldInject(MemberInfo member)
{
return member.IsDefined(
typeof(InjectHereAttribute),
true);
}
}
And finally add this behavior to the Ninject Kernel using the Components collection, it will run along the existing components, namely the default implementation of IInjectionHeuristic, which means either the default or the custom attribute can be used.
// Add custom inject heuristic
kernel.Components.Add<IInjectionHeuristic, CustomInjectionHeuristic>();
You can pass in another [attribute] type to the Kernel upon creation which can be used instead of InjectAttribute, but you'll still have to reference something centrally OOTB.
There was a similar question very recently about doing PI without attributes - there's no OOTB (as in directly on the fluent configuration interface) to put in a custom scanner but the extensibility points (you add a component that implements a Ninject interface as you build your Kernel that dictates how that aspect is to be work if looking for a given attribute isnt't what you want) are in there to determine where to inject based on Convention over Configuration - there's nothing stopping you amending the scanning to be based on just an attribute name (so it doesnt necessarily have to live in a central location).
Note that, in general, constructor injection is good for lots of reasons anyway, including this one, and keeping you code container agnostic is important (even if you're currently happy with one!)
I was able to accomplish this using a Heuristic class:
public sealed class MyInjectionHeuristic : NinjectComponent, IInjectionHeuristic
{
private static readonly IList<Type>
_propertyInjectible =
new List<Type>
{
typeof(IMyService),
};
/// <summary>
/// Returns a value indicating whether the specified member should be injected.
/// </summary>
/// <param name="member">The member in question.</param>
/// <returns><c>True</c> if the member should be injected; otherwise <c>false</c>.</returns>
public bool ShouldInject(MemberInfo member)
{
var info = member as PropertyInfo;
if( member == null || info == null )
return false;
if (info.CanWrite)
return _propertyInjectible.Contains(info.PropertyType);
if( this.Settings == null )
return false;
var propList = member.GetCustomAttributes(this.Settings.InjectAttribute, true);
return propList.Length > 0;
}
}
When creating your kernel:
var heuristics = _kernel.Components.Get<ISelector>().InjectionHeuristics;
heuristics.Add(new MyInjectionHeuristic());
Simple add additional types to the IList when you want to inject other types via properties.

Handling dependencies with IoC that change within a single function call

We are trying to figure out how to setup Dependency Injection for situations where service classes can have different dependencies based on how they are used. In our specific case, we have a web app where 95% of the time the connection string is the same for the entire Request (this is a web application), but sometimes it can change.
For example, we might have 2 classes with the following dependencies (simplified version - service actually has 4 dependencies):
public LoginService (IUserRepository userRep)
{
}
public UserRepository (IContext dbContext)
{
}
In our IoC container, most of our dependencies are auto-wired except the Context for which I have something like this (not actual code, it's from memory ... this is StructureMap):
x.ForRequestedType().Use()
.WithCtorArg("connectionString").EqualTo(Session["ConnString"]);
For 95% of our web application, this works perfectly. However, we have some admin-type functions that must operate across thousands of databases (one per client). Basically, we'd want to do this:
public CreateUserList(IList<string> connStrings)
{
foreach (connString in connStrings)
{
//first create dependency graph using new connection string
????
//then call service method on new database
_loginService.GetReportDataForAllUsers();
}
}
My question is: How do we create that new dependency graph for each time through the loop, while maintaining something that can easily be tested?
To defer the creation of an object until runtime, you can use a factory:
public interface ILoginServiceFactory
{
ILoginService CreateLoginService(string connectionString);
}
Usage:
public void CreateUserList(IList<string> connStrings)
{
foreach(connString in connStrings)
{
var loginService = _loginServiceFactory.CreateLoginService(connString);
loginService.GetReportDataForAllUsers();
}
}
Within the loop, do:
container.With("connectionString").EqualTo(connString).GetInstance<ILoginService>()
where "connectionString" is the name of a string constructor parameter on the concrete implementation of ILoginService.
So most UserRepository methods use a single connection string obtained from session, but several methods need to operate against a list of connection strings?
You can solve this problem by promoting the connection string dependency from IContext to the repository and adding two additional dependencies - a context factory and a list of all the possible connections strings the repository might need to do its work:
public UserRepository(IContextFactory contextFactory,
string defaultConnectionString,
List<string> allConnectionStrings)
Then each of its methods can build as many IContext instances as they need:
// In UserRepository
public CreateUserList() {
foreach (string connString in allConnectionStrings) {
IContext context = contextFactory.CreateInstance(connString);
// Build the rest of the dependency graph, etc.
_loginService.GetReportDataForAllUsers();
}
}
public LoginUser() {
IContext context = contextFactory.CreateInstance(defaultConnectionString);
// Build the rest of the dependency graph, etc.
}
We ended up just creating a concrete context and injecting that, then changing creating a wrapper class that changed the context's connection string. Seemed to work fine.

Resources