I am using Ninject
I have a class which I am using to hold & build some cached data if needed. It is set up in my Niject binding as follows
kernel.Bind<IConsistencyCheckCacheHelper>().To<ConsistencyCheckCacheHelper>().InSingletonScope();
The Class has some required dependencies injected into it the first time that the class is created, then that same instance is inject every time.
But in the case that the data needs to be rebuild I need run time dependency injected.
I am using this as a application wide cache,
Any ideas how to do this?
The Class has some required dependencies injected into it the first time that the class is created, then that same instance is inject every time.
The class has been registered with Ninject as a singleton. That means that the first time Ninject resolves an IConsistencyCheckCacheHelper it will create an instance of ConsistencyCheckCacheHelper, and then it will use that same instance over and over again.
So Ninject isn't injecting the same instance of a dependency into ConsistencyCheckCacheHelper over and over. It's only creating one instance of ConsistencyCheckCacheHelper, so whatever instance of the dependency gets injected into it won't change either.
If you want the dependency within used by ConsistencyCheckCacheHelper to change each time it's resolved then you can't register it as a singleton. You would need to use a different scope.
.InTransientScope() (the default) means that every time a type is resolved a new instance is created.
.InRequestScope() means that a new instance is created for every web request.
It's still a tiny bit more complicated than that. For example, if ConsistencyCheckCacheHelper is registered as transient, a new instance is created each time. But if it depends on something else and that dependency is registered as a singleton, each new instance of ConsistencyCheckCacheHelper will receive the same singleton instance of that dependency.
It's often recommended that we start off with transient dependencies. Unless we specifically need to reuse an instance, the cost of creating new objects likely isn't that great. For a web application, InRequestScope is likely safe. I'd only use singleton scope if I'm sure that I can safely reuse one instance of that class along with one instance if its dependencies and their dependencies and so on.
Ninject object scopes
This may not be the best way to do this but it works, Create 2 Interfaces that represent the same class
public interface DepInterfaceOne
{
int MethodWithCachedData();
void InfoRequiredForAtRunTime(object RunTimeObject);
}
public interface DepInterfaceTwo: IConsistencyCheckCacheHelper
{
}
And Set up your binding in this way
kernel.Bind<DepInterfaceOne>().To<DepInterfaceOneClass>().InSingletonScope();
kernel.Bind<DepInterfaceOneTwo>().ToMethod(a =>
{
DepInterfaceOne toReturn = kernel.Get<DepInterfaceOne>();
toReturn.InfoRequiredForAtRunTime(HttpContext.Current.Session["InfoRequired"]);
return toReturn;
});
Related
I want to use same technology to access my database both from ASP.NET MVC and WPF and decided to use EF Core.
In ASP.NET I can inject DbContext(UnitOfWork, AppBLL etc) into Controller and its lifecycle is scoped to request/response operation. As I understood the scope is created behind the scenes using ASP.NET middleware pipeline.
In WPF however scope must be defined based on the app use case which is completely logical since some times there is need for long operation (for example using DbSet.Local.ToObservableCollection() and DataGrid) and sometimes operation is more trivial (for example update one entity).
I want to achieve somewhat similar behavior to ASP.NET MVC in WPF, basically I want to inject DbContext into ViewModel constructor and then each method to be its own scope thus have different short-lived DbContext each method call.
I use Microsoft.Extensions.DependencyInjection and CommunityToolkit.MVVM for DI and add DbContext using AddDbContext. This makes it scoped but without defining the scopes it is effectively singleton. I do not want to define scope with using(var scope = ...) and GetRequiredService each time I make a db operation since it will pollute my code.
As I said I want it to be sleek like in ASP.NET.
So I tried aspect oriented programming with PostSharp but feels kinda dull to add attributes to each method that uses DbContext also there are concerns about testability.
I tried implementing abstract class which has methods to which lambda with operation is passed and lambda is created inside a using(var scope = ...) expression and thus uses scoped DbContext. At the disposal of the scope DbContext is automatically disposed with it.
These approaches however are still distant from ASP.NET mechanism and
I want DbContext lifecycle to be managed smarter.
If I define DbContext as transient then it is only created on injection into ViewModel and not re-created for methods.
By the way, do I understand correctly that in ASP.NET when DbContext is injected into Controller it is disposed right after the construction, since the scope is finished?
EDIT:
Here is a link to example project Github repository
https://github.com/anguzo/ef-core-in-wpf-example
WpfApp project is example of the problem - you can't update same entity twice since it's already being tracked.
Other WPF projects demonstrate different solutions to this problem I came up with.
The closest to the ASP.NET behavior is using PostSharp custom attribute. It requires attribute to be applied to ViewModel class and modifies each method(excluding "special methods": getters, setters and consturctors).
I am still lost since official Microsoft documentation and other materials on the Internet do not describe proper solution to this problem.
The dependency injection container is an instance class.
With mvc there is a request pipeline that provides the parameters of anything instantiated by it from that container.
The difference between mvc and wpf is that with wpf you don't have that pipeline so you need to provide the container instance somehow whenever you instantiate a class you want anything injected to.
It's covered pretty well here:
https://learn.microsoft.com/en-us/windows/communitytoolkit/mvvm/ioc
You do not want everything to be a singleton and you do not want to resolve the entire object graph as you crank up your application.
As you spotted, that's impractical anyhow because you want some things to be transient.
Passing the DI container around is a nuisance. You might have any number of layers down to your dbcontext.
What is usual is to make the injection container available throughout the app.
In the code there, they've added a property to App to stash that instance in:
public sealed partial class App : Application
{
public App()
{
Services = ConfigureServices();
this.InitializeComponent();
}
/// <summary>
/// Gets the current <see cref="App"/> instance in use
/// </summary>
public new static App Current => (App)Application.Current;
/// <summary>
/// Gets the <see cref="IServiceProvider"/> instance to resolve application services.
/// </summary>
public IServiceProvider Services { get; }
App.Services is your dependency injection container. The magic bag you grab your instances out of.
Where these services are registered they're all singletons there, but your dbcontext should be
services.AddTransient<IMyDbContext, MyDbContext>();
And your repository would take an IMyDbContext in it's constructor which would be supplied out the container.
You need to reference that container exposed by App to resolve an instance:
var repo = App.Current.Services.GetService<IRepository>();
Because it's on App.Current, everywhere in your code will be able to reference it. So long as you have a regular wpf entry point.
Your repository would get an instance of dbcontext via injection and you'd so whatever you're doing with that repository. Once it goes out of scope the repository and dbconnection would be ready for garbage collection so long as they're both Transient.
Transients will be disposed after they go out of scope. Hence if you pass a transient dbcontext down from a mvc controller then it will stay in scope until the response is sent from the controller. It's only going to be torn down after the controller's returned it's result and goes out of scope.
The aspect of the code which I would change is to add an abstracted facade around the di container. You want to be able to moq whatever grabs a class instance out that container if you use it within any classs. If you use app.current in unit testing then you need to instantiate an application object.
What Andy outlines is pretty much what I use, it's commonly referred to as a Service Locator pattern, and has a bit of a reputation as an anti-pattern, but for WPF it is pretty effective if you have some discipline within your team about where and how it is allowed to be used.
I'd recently written a quick snippet on using the ServiceLocator pattern and lazy dependency properties with Autofac which can provide some ideas on how the pattern can be applied:
private readonly IContainerScope _scope;
private ISomeDependency? _someDependency = null;
public ISomeDependecy SomeDependency
{
get => _someDependency ??= _scope.Resolve<ISomeDependency>()
?? throw new ArgumentException("The SomeDependency dependency could not be resolved.");
set => _someDependency = value;
}
public SomeClass(IContainer container)
{
if (container == null) throw new ArgumentNullException(nameof(container));
_scope = container.BeginLifetimeScope();
}
public void Dispose()
{ // TODO: implement proper Dispose pattern.
_scope.Dispose();
}
This gives you a pattern gives you a default lifetime scope for the life of a top-level dependency which could be a MVVM ViewModel, and/or navigation provider, etc. so your dependencies can be managed by Transient, Singleton, or PerLifeTimeScope. (Suited to something like the EF DbContext) So for instance when a form is loaded the DbContext instance can be resolved for the lifetime of that form.
I call the pattern a lazy property pattern as the actual dependency is resolved only if/when it is accessed via the property. The advantage of this is when writing unit tests with classic constructor injection, you need to mock every dependency for every test, where with "lazy" properties you use the Setter for just the dependencies you need. The initialization of the class under test accepts a mocked container that simply throws an exception to fail the test if it's Resolve<T> method is called. (No need to build a functional mock container for tests to resolve mocked dependencies or other such complexity)
The caveat of this pattern, and one suggestion to work with the team on to check is that the _scope reference should only be accessed from the dependency properties, not willy-nilly through the code to resolve dependencies ad-hoc. For instance if a new dependency is needed, declare the property accessor to resolve via the scope rather than just writing a _scope.Resolve<NewDependency>() in the code. While you can still test around such code, you'd need to set up your tests to provide a _scope capable of resolving a Mock, which is honestly messy. Following the property pattern makes testing a lot simpler to provide the expected dependency via the Setter and getting an exception/failure if an unexpected dependency happens to get accessed.
It's not proper-C#-Lazy, though I do use a proper Lazy dependency pattern for injected dependencies, and web projects where the lifetime scope is conveniently managed:
private readonly Lazy<ISomeDependency>? _lazySomeDependency = null;
private ISomeDependency? _someDependency = null;
public ISomeDependency SomeDependency
{
get => _someDependency ??= _lazySomeDependency?.Value
?? throw new ArgumentException("SomeDependency dependency was not provided.");
set => _someDependency = value;
}
public SomeClass(Lazy<ISomeDependency>? someDependency = null)
{
_lazySomeDependency = someDependency;
}
Autofac does support lazy initialization so this pattern means that for normal execution, Autofac provides the properties as Lazy references which will resolve if/when they are accessed. For unit tests, you just initialize with an empty constructor and use the Setters to set the dependencies you expect to actually be used. The above example with 1 dependency doesn't really demonstrate the value of that, but picture a test suite for a class that has 8 or 12 dependencies where a method under test will likely only touch a couple of them.
Like the below code, I have to use the factory/func way of registration with container as I don't know the value of "userId" property ahead of time but only during runtime. This is working & no issues with functionality aspects.
container.AddSingleton<IBLogic, BLogic>(); //explicitly registration 'BLogic' service object
container.AddSingleton<Func<string, IDBCache>>
(p=> (userId) => new IDBCache(userId, p.GetService<IBLogic>()));
Since here I'm using "new IDBCache", as per the link framework does not dispose of the services automatically.
Questions:
To make framework to dispose of the services automatically, is there any way out?
container.AddSingleton<Func<string, IDBCache>>
(p=> (userId) => new IDBCache(userId, p.GetService()));
Since I'm just registering the definition of func/factory not the service object(like 'BLogic') as such, does AddSingleton provides any advantage over using 'AddScoped' or 'AddTransisent' like below?
container.AddTransisent<Func<string, IDBCache>>
(p=> (userId) => new IDBCache(userId, p.GetService<IBLogic>()));
There's no easy fix for this. MS.DI doesn't contain a RegisterForDisposal method that you can call. You will have to create a separate wrapper that implements disposable to which you can hook your created instances. For instance:
services.AddSingleton<IBLogic, BLogic>();
services.AddScoped<DisposeWrapper>();
services.AddScoped<Func<string, IDBCache>>(p => (userId) =>
{
var cache = new IDBCache(userId, p.GetRequiredService<IBLogic>());
p.GetRequiredService<DisposeWrapper>().Add(cache);
return cache;
});
Where the DisposeWrapper looks like this:
public sealed class DisposeWrapper : List<IDisposable>, IDisposable
{
public void Dispose()
{
// Dispose in reverse order as creation.
for (int i = this.Count - 1; i >= 0; i--) this[i].Dispose();
}
}
Such implementation, however, comes with quite some caveats, because DisposeWrapper should be registered using the same scope as you want to cache your IDBCache. That's why in the example above, I registered both DisposeWrapper and the factory as Scoped.
Registering DisposeWrapper as Singleton, means that created IDBCache instances will only get disposed when the application ends. If you create many IDBCache instances during the lifetime of the application, it will cause a memory leak. This is unlikely a good idea in your scenario.
Registering both as transient, on the other hand, could still (confusingly) cause memory leaks, because the factory could be injected into a singleton, causing it (and its DisposeWrapper) to become a Captive Dependency.
Because of the complications of this design, I recommend changing your design.
If you redesign IDBCache in such way that runtime data isn't required during object construction, you can allow IDBCache to be registered in the container without factory (e.g. AddTransient<IDBCache>()) which allows it to be disposed normally by the container. This will remove all above-introduced complexity.
So I am working on API and using Ninject for DI & IoC. I know how the basic code works using Ninject but in the constructor of one of the classes an object of Logger is being sent. Rather than send it in constructor design item I would like to pass it in NinjectWebCommon.cs file.
public GAMonthlyAPIController() : this(new GAMonthlySQLReader(new NullLogger()))
This is the constructor.
kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
This is the entry in NinjectWebCommon.cs I would like to bind it in NinjectWebCommon.cs rather than default value. How would I pass that? I don't even know what to search for, so I could find answers.
The most practical way to apply the dependency injection pattern is to use constructor injection. This means that the classes GaMonthlyAPIController depend on should be passed in through the constructor, rather than hard-coded inside of the controller.
public class GAMonthlyAPIController
{
private readonly IGAMonthlySQLReader gaMonthlySqlReader;
public GAMonthlyAPIController(IGAMonthlySQLReader gaMonthlySqlReader)
{
this.gaMonthlySqlReader = gaMontlySqlReader
?? throw new ArgumentNullException(nameof(gaMontlySqlReader));
}
// implementation of controller...
}
This should be the only constructor for your controller class. The controller itself doesn't know anything about GAMontlySqlReader or any of its dependencies.
The same goes for GAMonthlySQLReader - it will allow any ILogger implementation to be injected through the constructor.
The idea is that it puts the composition root of the application in charge of how the dependencies are composed together, meaning you can easily switch them around later without making any changes to the components that you are composing. So, Ninject would be used inside of your composition root to map types to their abstraction, and then will build object graphs of all of those dependencies composed together.
kernel.Bind<ILogger>().To<MyLoggerClass>();
kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
For each of the application services, you would allow Ninject to instantiate them (so it can supply the dependencies) rather than using the new keyword inside of your application (new can be used for DTOs and Models, though).
I think you need to add Ninject.Web.WebApi using nuget to your Web Api project. Then use Ninject for creating ApiControllers:
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
And add the Bind() for GAMonthlyAPIController. No need to create a default constructor for your controller.
Have a look to this post:
http://nodogmablog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/
I am trying to figure out how to get a new lifetime scope each time I resolve an instance from the container. I would like to do this without the depending component needing to know about Autofac.
I'm creating a .NET Core server application (console app) which has a "master server" (IMasterServer) component and zero or more "session server" (ISessionServer) components. Both the master and the session servers have their own IMessageBroker dependency. The master server will create a new session server whenever it gets a message from the message broker.
The catch is that each session server instance needs its own IMessageBroker, and I don't think I can use InstancePerDependency() because other sub-components of ISessionServer will also need to access the IMessageBroker so the message broker needs to be single instance within the scope of a session. So my thinking is that when the master server spawns a new session, it should do so within a new lifetimescope, and I can register the IMessageBroker dependency using InstancePerLifetimeScope().
So, the question is, how can I inject an ISessionServer factory into IMasterServer such that each time that factory is called, a new lifetime scope is created for the resulting ISessionServer instance? And how can this be done such that none of the components need to know about Autofac?
These two SO questions both suggest using the Owned<T> relationship:
Can I create an implicit Lifetime scope within a factory?
Is it possible to create a new scope whenever a component is resolved?
However, unless I'm missing something, that means that the component into which the dependency will be injected (IMasterServer in my case) needs to know about Autofac, because its ctor signature must include the Owned<T> type.
What I have so far:
using Autofac.Features.OwnedInstances;
class MasterServer : IMasterServer
{
private IMessageBroker mMessageBroker;
private Func<Owned<ISessionServer>> mSessionServerFactory;
public Master(
Func<string, IServerMessageBroker> messageBrokerFactory,
Func<Owned<ISessionServer>> sessionServerFactory
)
{
mMessageBroker = messageBrokerFactory("master");
mSessionServerFactory = sessionServerFactory;
}
}
class SessionServer : ISessionServer
{
private IMessageBroker mMessageBroker;
private string mId;
public SessionServer(
Func<string, IMessageBroker> messageBrokerFactory
)
{
mId = Guid.NewGuid().ToString();
mMessageBroker = messageBrokerFactory(mId);
}
}
You can see that the MasterServer concrete class needs to use the Autofac.Features.OwnedInstances namespace in order to define the session factory using the Owned<T> relationship type.
How can I use Autofac to create a new lifetime scope each time ISessionServer is resolved through the factory injected into the MasterServer, without the components needing to know anything about the specific DI container in use?
I always felt that letting Autofac-specific code slip onto factory classes is the less of two evils.
So, if I was in you, I would just use the Owned<T> class, call it a day and move on. It's an excellent solution and keeps all the disposing of every component automagical as always with Autofac.
Just remember to call Dispose or your owned SessionServer when needed, or you will leak resources.
AFAICT the Autofac approach doesn't let you write 100% DI free code. So you need to reference it, someway, somewhere.
A single reference to include Owned<T> seems a pretty acceptable trade off.
Let me point out a problem in your design (or in the part you included): there is no simple way to link a ISessionServer into a disposable scope.
E.g: you expose a factory class, and then the SessionServer is out on his own.
Managing scopes in this way becomes hard.
A cleaner approach is to use a Disposable into a using statement:
using (var sessionServer = sessionFactory.GetServer())
{
// do something with sessionServer.
}
I have a problem with EF not returning the newest data in a 3 layered WPF application, and I suspect it has something to do with how I handle the lifetime of my context. This is the scenario:
There are several repositories wrapped inside a UnitOfWork. There is also one service (MyService), which uses the UnitOfWork. This UnitOfWork must also be called from the UI directly, without passing through a service.
In the ViewModel of my main window at some point I create a new window (using ViewModel first):
var dialog = new DialogViewModel(_eventAggregator, _unitOfWork, Container.Resolve<CarService>());
This main window ViewModel has a UnitOfWork, which has been injected in the constructor, and that is passed to the DialogViewModel.
CarService's constructor also needs a UnitOfWork, which is also injected in its constructor:
public CarService(IUnitOfWork unitOfWork){
_unitOfWork = unitOfWork;
}
When CarService is used in DialogViewModel to make a query to retrieve some data and make some updates, it works fine the first time. However, when the same query is made the next time to retrieve that data, instead of returning the newest modified one it returns the old/cached one. The query using UnitOfWork (inside CarService) looks like this:
var values = _unitOfWork.GarageRepository.GetSomeValues();
_unitOfWork.GarageRepository.MakeSomeChangesToTheValuesUsingStoredProcedure();
The second time this is called, values doesn't contain the newest version of the data; however it has been updated successfully in the DB.
I'm doing DI using Unity, and this is how my container looks like:
public class Container
{
public static UnityContainer Container = new UnityContainer();
// Called once in the AppBoostraper, as soon as the GUI application starts
public void BuildUp()
{
Container.RegisterType<IUnitOfWork, UnitOfWork>();
Container.RegisterType<ICarService, CarService>();
}
}
Why isn't the right data being returned, and how can I fix it?
I finally found the problem, which had to do with my management of the unitOfWork/dbcontext lifecycle.
I was loading some entities, then updating them with a stored procedure (so the entities in the code were not up to date anymore), and then loading the queries again; at this point EF was getting the values from the cache rather than from the DB.
I found two ways of fixing this:
A rather "hacky" one, force the entities to reload:
Context.Entry(entity).Reload();
Encapsulate the unitOfWork usage with a using, so that the context is disposed at the end of each transaction and thus getting fresh data the next time. I think this is more in line with what the UnitOfWork is meant for and feels more robust to me. I've also wrapped the UnitOfWork in a factory, so now that gets injected in the constructors.
using (var uOw = new unitOfWorkFactory.GetNew())
{
// make the queries
}
The default LifetimeManager for Unity is the TransientLifetimeManager, which means you get a new instance each time it resolves (including when injected). So given your registrations, you'll get a new CarService, with a new instance of a UnitOfWork each time you call Resolve(), and a new, different instance injected into your main window ViewModel.
So your ViewModel gets a UoW, the CarService gets a separate UoW, and updating one will mean the other is now out of date due to caching.
What you need to do is set up a LifetimeManager for the context that has appropriate scope, or defer to a factory. Unity doesn't have that many LMs built in, but the LifetimeManager class is basically a glorified map (has a Set, Get, and Remove method essentially).
I don't know enough about WPF and its lifetimes to suggest an implementation. Maybe it can be singleton (which will keep the same context the entire time the program is running), maybe it can be backed by a thread's CallContext.
Your other option is to pass along the UoW instance when you resolve the CarService by calling Container.Resolve<CarService>(new ParameterOverride("unitOfWork", _unitOfWork)). That'll keep the lifecycle management tied to the lifetime of the main window ViewModel. However, this approach has problems because your VM class knows a little too much about the CarService (notably, that it has a UoW in it).