I have a Repository which has a dependency of User
I need to put other implementation of User
and I can do it like that, but with this approach I do not know how to mock my repository
private readonly IRepository<Entity> _repository;
public SomeClass(MyAppDbContext context)
{
_repository= new EfRepository<WorkOrder>(context, new User());
}
Is there a way to inject a specific implementation of User
here, or how I can test the code I wrote
CodePudding user response:
Just as you inject MyAppDbContext
into SomeClass
you can also inject an instance of User
, e.g.
private readonly IRepository<Entity> _repository;
public SomeClass(MyAppDbContext context, User user)
{
_repository= new EfRepository<WorkOrder>(context, user);
}
You can either register User
in the IoC like this:
services.AddTransient<User>();
In case you have already registered a service for User
and want to use another instance, you can register a factory method for SomeClass
that sets up the User
instance:
services.AddScoped<SomeClass>(prov => new SomeClass(
prov.GetRequiredService<MyAppDbContext>(),
new User()));
The factory method approach is viable if you only have a few spots that need the special instance, otherwise you can use this approach: Unlike other IoCCs, the .NET Core IoCC does not support named registrations, but you can also use some kind of "marker interface" to register another instance:
public interface ISpecialUser : IUser {}
public class User : IUser
{
// ...
}
public class AnotherUser : ISpecialUser
{
// ...
}
// ...
public SomeClass(MyAppDbContext context, ISpecialUser user)
{
_repository= new EfRepository<WorkOrder>(context, user);
}
// ...
services.AddScoped<IUser, User>();
services.AddScoped<ISpecialUser, AnotherUser>();
In the tests, you can set up an instance of User
that suits your needs and use the new constructor parameter.