Using Ninject with mocks in F# - ninject

This question is part of larger question that can be found here
As in out production code we use Ninject and constructor injection our services tend to look like this
public class Service : IService
{
private readonly IRepository _repository;
public Service(IRepository repository)
{
_repository = repository;
}
public Task<IEnumerable<SelectOption>> GetAlLogicOptions()
{
return _repository.GetOptionsAsync();
}
}
how ever list of constructor parameters may and will change over time. This is the reason that we want to have IoC to also be used in tests.
In C# NUnit this is quite easy as we have Ninject.MockingKernel that always provides mock implementation and in each test fixture we just rebind sut to it real implementation.
How to achieve same thing in F# xUnit.

Related

NHibernate, injecting service into IUserType using .NET Core ioc container

Is it possible to inject a service into a UserType ?
internal class MyUserType : IUserType
{
private static ISerializer _serializer;
public MyUserType (ISerializer serializer)
{
_serializer = serializer
}
}
Tried the why it is suppose to work for all but fails, stating it needs a default parameterless constructor
I don't think this is going to be possible as you would need to tap into NH's component creation pipeline/process, which, AFAIK, isn't readily exposed.
You could use property injection with a 'local default'. This would allow you to depend on the ISerializer abstraction and replace it when necessary, testing maybe, but rely on a default concrete type in an environment that didn't support IoC.
internal class MyUserType : IUserType
{
private static ISerializer _serializer = new ConcreteSerializer();
public JsonShippingDetailsUserType()
{
}
public ISerializer Serializer { get; set; }
}
N.B. This is a really naive implementation of property injection. If you go with this solution you'll need to 'harden' the code. Mark Seemann's DI book has an excellent example.
The thing is that IUserType is managed by NHibernate which uses its own IoC container and by implication does not have access to your IoC of choice and again by implication does not have access to any services registered on your IoC of choice. There is not easy way of injecting, what I can think of is some sort of proxy or to somehow get access to NHibernate internals.

Autofac Register closed types and retrieve them at run time

I have an Interface that will take in a generic type T
internal interface IQuestion<T> where T : IWithOptionsId
{
Task<T> Provide(Guid id);
}
Following by that I will implement this interface in multiple classes. For example
public class SomeProvider : IQuestion<OptionsClass>
{
private readonly IRepository _repository;
public SomeProvider(IRepository repository)
{
_repository = repository;
}
public async Task<OptionsClass> Provide(Guid id)
...
}
To register this with outofac I used this
Autofac.RegisterAssemblyTypes(
Assembly.GetExecutingAssembly())
.AsImplementedInterfaces()
.AsClosedTypesOf(typeof(IQuestion<>));
My question is this. I have multiple instances for this interface. How do I access different instance once at the run time? If my IQuestion<T> will take in Options class and also it will take in Answer class how can I get an instance of those classes during run time?
I'm pretty sure you can just inject the instance itself. Not great practice, but it should work:
public SomeClass(SomeProvider<OptionsClass> provider)
You could also try creating a named instance when you register it, and inject that. See this and this.

Do we need interfaces for dependency injection?

I have an ASP.NET Core application. The application has few helper classes that does some work. Each class has different signature method. I see lot of .net core examples online that create interface for each class and then register types with DI framework. For example
public interface IStorage
{
Task Download(string file);
}
public class Storage
{
public Task Download(string file)
{
}
}
public interface IOcr
{
Task Process();
}
public class Ocr:IOcr
{
public Task Process()
{
}
}
Basically for each interface there is only one class. Then i register these types with DI as
services.AddScoped<IStorage, Storage>();
services.AddScoped<IOcr,Ocr>();
But i can register type without having interfaces so interfaces here look redundant. eg
services.AddScoped<Storage>();
services.AddScoped<Ocr>();
So do i really need interfaces?
No, you don't need interfaces for dependency injection. But dependency injection is much more useful with them!
As you noticed, you can register concrete types with the service collection and ASP.NET Core will inject them into your classes without problems. The benefit you get by injecting them over simply creating instances with new Storage() is service lifetime management (transient vs. scoped vs. singleton).
That's useful, but only part of the power of using DI. As #DavidG pointed out, the big reason why interfaces are so often paired with DI is because of testing. Making your consumer classes depend on interfaces (abstractions) instead of other concrete classes makes them much easier to test.
For example, you could create a MockStorage that implements IStorage for use during testing, and your consumer class shouldn't be able to tell the difference. Or, you can use a mocking framework to easily create a mocked IStorage on the fly. Doing the same thing with concrete classes is much harder. Interfaces make it easy to replace implementations without changing the abstraction.
Does it work? Yes. Should you do it? No.
Dependency Injection is a tool for the principle of Dependency Inversion : https://en.wikipedia.org/wiki/Dependency_inversion_principle
Or as it's described in SOLID
one should “depend upon abstractions, [not] concretions."
You can just inject concrete classes all over the place and it will work. But it's not what DI was designed to achieve.
No, we don't need interfaces. In addition to injecting classes or interfaces you can also inject delegates. It's comparable to injecting an interface with one method.
Example:
public delegate int DoMathFunction(int value1, int value2);
public class DependsOnMathFunction
{
private readonly DoMathFunction _doMath;
public DependsOnAFunction(DoMathFunction doMath)
{
_doMath = doMath;
}
public int DoSomethingWithNumbers(int number1, int number2)
{
return _doMath(number1, number2);
}
}
You could do it without declaring a delegate, just injecting a Func<Something, Whatever> and that will also work. I'd lean toward the delegate because it's easier to set up DI. You might have two delegates with the same signature that serve unrelated purposes.
One benefit to this is that it steers the code toward interface segregation. Someone might be tempted to add a method to an interface (and its implementation) because it's already getting injected somewhere so it's convenient.
That means
The interface and implementation gain responsibility they possibly shouldn't have just because it's convenient for someone in the moment.
The class that depends on the interface can also grow in its responsibility but it's harder to identify because the number of its dependencies hasn't grown.
Other classes end up depending on the bloated, less-segregated interface.
I've seen cases where a single dependency eventually grows into what should really be two or three entirely separate classes, all because it was convenient to add to an existing interface and class instead of injecting something new. That in turn helped some classes on their way to becoming 2,500 lines long.
You can't prevent someone doing what they shouldn't. You can't stop someone from just making a class depend on 10 different delegates. But it can set a pattern that guides future growth in the right direction and provides some resistance to growing interfaces and classes out control.
(This doesn't mean don't use interfaces. It means that you have options.)
I won't try to cover what others have already mentioned, using interfaces with DI will often be the best option. But it's worth mentioning that using object inheritance at times may provide another useful option. So for example:
public class Storage
{
public virtual Task Download(string file)
{
}
}
public class DiskStorage: Storage
{
public override Task Download(string file)
{
}
}
and registering it like so:
services.AddScoped<Storage, DiskStorage>();
Without Interface
public class Benefits
{
public void BenefitForTeacher() { }
public void BenefitForStudent() { }
}
public class Teacher : Benefits
{
private readonly Benefits BT;
public Teacher(Benefits _BT)
{ BT = _BT; }
public void TeacherBenefit()
{
base.BenefitForTeacher();
base.BenefitForStudent();
}
}
public class Student : Benefits
{
private readonly Benefits BS;
public Student(Benefits _BS)
{ BS = _BS; }
public void StudentBenefit()
{
base.BenefitForTeacher();
base.BenefitForStudent();
}
}
here you can see benefits for Teachers is accessible in Student class and benefits for Student is accessible in Teacher class which is wrong.
Lets see how can we resolve this problem using interface
With Interface
public interface IBenefitForTeacher
{
void BenefitForTeacher();
}
public interface IBenefitForStudent
{
void BenefitForStudent();
}
public class Benefits : IBenefitForTeacher, IBenefitForStudent
{
public Benefits() { }
public void BenefitForTeacher() { }
public void BenefitForStudent() { }
}
public class Teacher : IBenefitForTeacher
{
private readonly IBenefitForTeacher BT;
public Teacher(IBenefitForTeacher _BT)
{ BT = _BT; }
public void BenefitForTeacher()
{
BT.BenefitForTeacher();
}
}
public class Student : IBenefitForStudent
{
private readonly IBenefitForStudent BS;
public Student(IBenefitForStudent _BS)
{ BS = _BS; }
public void BenefitForStudent()
{
BS.BenefitForStudent();
}
}
Here you can see there is no way to call Teacher benefits in Student class and Student benefits in Teacher class
So interface is used here as an abstraction layer.

Inject DbContext in Asp.Net Core. Concrete type or interface?

On an Asp.Net Core project I am injecting Entity Framework DbContext:
public MessageRepository(MyDbContext context) {
}
And the configuration is:
services
.AddEntityFramework()
.AddSqlServer()
.AddDbContext<Context>(x => x.UseSqlServer(connectionString);
Should I create an interface, IMyDbContext, and injecting it instead?
public class MyDbContext : DbContext, IMyDbContext { }
public MessageRepository(IMyDbContext context) {
}
In all ASP.NET Core examples I see the concrete type, MyDbContext, is being injected and not an interface ...
What option should I choose?
Currently working on a project myself, where I decided to go with 2 interfaces like this
public interface IDbContext : IDisposable
{
DbContext Instance { get; }
}
and
public interface IApplicationDbContext : IDbContext
{
DbSet<MyEntity> MyEntities { get; set; }
...
}
My concrete DbContext would then just implement the application context interface
public class ApplicationDbContext : DbContext, IApplicationDbContext
{
public DbContext Instance => this
public DbSet<MyEntity> MyEntities { get; set; }
}
This allows my implementation of the Application context to be injected as the application context interface, while also providing me access to the DbContext methods through the Instance property getter without having to add methods needed from the DbContext class to the interface.
Until now, this works great.
We're always injecting an interface, since it's easier to mock in unit and integration tests.
Are you willing to change the signature of the MessageRepository constructor? It relies on the concrete type.
Do you write tests for your code? Using and interface would make it easier to mock the database context.
If you've answered "no" to one or more of the above, inject the concrete type; otherwise, inject the interface.
[EDIT]
use the following.
context services.AddScoped<IApplicationDbContext>(provider => provider.GetService<ApplicationDbContext>());
In my opinion, you should always rely on an interface as #Uli said, but when it comes to the DbContext you need to take in mind that you are exposing all methods of the DbContext of EntityFramework Core
public class MyDbContext : DbContext, IMyDbContext { }
in that case, you don't need to implement any method that you are exposing because DbContext handles that for you.
BUT if EF code change the DbContext and you make an update to your project then you will be on a painful situation of updating your IMyDbContext every time, also all your unit testing. In my opinion, that will give you a lot of headaches.
This answers/questions can help you to understand why https://stackoverflow.com/a/6768712/819153
Unit testing EF - how to extract EF code out from BL?

What is the benefit of using a Ninject.Factory over just injecting the IKernel?

According to this article (first paragraph), it is bad practice to inject your IKernel into wherever you need it.
Instead it is proposed to introduce a factory interface that is automatically implementend by Ninject (doing internally the same resolution).
This is an actual code snipped I am working on:
Former implementation:
public class CommandServer
{
[Inject]
public IKernel Kernel { get; set; }
....
public TResponse ExecuteCommand<TRequest, TResponse>(TRequest request)
where TResponse : ResponseBase, new()
{
...
var command = Kernel.Get<ICommand<TRequest, TResponse>>();
...
}
}
Using a factory:
public class CommandServer
{
[Inject]
public ICommandFactory CommandFactory { get; set; }
....
public TResponse ExecuteCommand<TRequest, TResponse>(TRequest request)
where TResponse : ResponseBase, new()
{
...
var command = CommandFactory.CreateCommand<TRequest, TResponse>();
...
}
}
// at binding time:
public interface ICommandFactory
{
ICommand<TRequest, TResponse> CreateCommand<TRequest, TResponse>();
}
Bind<ICommandFactory>().ToFactory();
I am not saying I don't like it (it looks nice and clean) - just not exactly sure why the former is particularly bad and the latter is so much better?
Generally you should not be using the Service Locator pattern. Why you ask? Please see Mark Seeman(comments, too!) and this SO question. Using the IKernel (or somewhat better: only the IResolutionRoot part of it) smells like Service Locator.
Now Mark would suggest that you should apply the Abstract Factory Pattern instead - and he also mentions the Dynamic proxy approach.
I personally think that using ninject auto-generated factories (= dynamic proxy approach) instead is worth the trade off.
You should not use a factory like:
public interface IServiceLocator
{
T Create<T>();
}
because well.. it's service locator ;-)
However, using something like
public interface IResponseHandleFactory
{
IResponseHandle Create(int responseId);
}
is perfectly fine.
Of course you can also do this by using the IResolutionRoot directly - instead of the factory. The code would look like:
IResolutionRoot.Get<IResponseHandle>(
new ConstructorArgument("responseId", theResponseIdValue);
Reasons not to use IResolutionRoot directly
A lot of the IResolutionRoot "methods" are in fact extension methods. That complicates unit-testing a lot (it's basically not a sensible choice if you want to unit test it, at all).
slight worse decoupling from container (=> ease of changing DI containers) than when using a factory interface. The auto-generated factory feature you can also implement as an add on to other containers - if they don't have it already (i've done so personally for Unity and AutoFac). However it requires some know-how about dynamic proxies.
Alternative to factory interfaces: Using Func<> factories. The above example could also be replaced by Func<int, IResponseHandle>(). Quite a lot DI containers support this out of the box / with standard plugins (ninject needs the Factory extension). So you'd be decoupled from the container even more. Disadvantage: harder to unit test and not clearly named parameters.