Injecting an object InRequestScope into a ValidationAttribute via Ninject throws error - asp.net-mvc-4

Ninject now enables property injection into ValidationAttribute (https://github.com/ninject/ninject.web.mvc/wiki/Injection-of-validators). It works great, UNTIL you use bind the object InRequestScope().
So, here is what I think is happening. ValidationAttribute are implemented as singletons in ASP.NET.
The first time an attribute is instantiated, Ninject properly populates the injected property.
The object that was injected is disposed when the current request ends
Upon the next request, accessing the injected property throws an error because it has been disposed.
Ninject does not try to populate the injected property because the validation attribute is never re-instantiated.
Does this make sense? Does anyone have any idea for a work around?

That is correct.
If you really need a dependency in request scope then you have to inject a factory for the dependency instead of the dependency itself and use it to get a new instance during evaluation.

Related

Accessto DI object after request finished. asp .net core 2.1

I want to acces dbcontext DI object after request finished, e.g. do some background task atfet request complete and keep it short.
sample code:
await bunusInfoService.CheckBonus(user.Id, _appSettings.GregSysRegisterIP);
UserDto uss = Mapper.Map<UserDto>(user);
return uss;
but call of bunusInfoService.CheckBonus without await.
it says:
Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.

Autofac scope in ASP.NET Core appears to differ between middleware

When registering an object with Autofac and resolving in middleware and again in the MVC middleware via a controller, the instance is different. Instances are registered per lifetime scope.
I've popped a repro project here https://github.com/jakkaj/AutofacResolveIssue.
The app sets a value to the IUserService in the middleware, then try to read that value in the ValuesController later.
This same technique worked in older versions of ASP.NET with autofac. Any ideas what's going on?
Okay, so I made the mistake of injecting my dependency in to the constructor of the middleware.
You should inject dependencies into the Invoke.
The entire middleware object is singleton across all app instances!
Change builder registration to use SingleInstance() insted of InstancePerLifetimeScope(), So that every dependent component or call to Resolve() gets the same, shared instance.
builder.RegisterAssemblyTypes(typeof(UserService).GetTypeInfo().Assembly)
.Where(t => t.Name.EndsWith("Service") || t.Name.EndsWith("Repo"))
.AsImplementedInterfaces()
.SingleInstance();
Single Instance This is also known as ‘singleton.’ Using single instance scope, one instance is returned from all requests in
the root and all nested scopes. When you resolve a single
instance component, you always get the same instance no matter where
you request it.
Check the link for more details
http://docs.autofac.org/en/latest/lifetime/instance-scope.html#single-instance

createCache fails in non-static method

I am creating a cache with a CacheStoreFactory implementation and a CacheStoreSessionListener. If I set the CacheConfiguration with these fields and then call createCache but in an INSTANCE method I get this exception:
Exception in thread "main" javax.cache.CacheException: class
org.apache.ignite.IgniteCheckedException: Failed to validate cache
configuration (make sure all objects in cache configuration are
serializable): LongCache
In a static method, this does not occur. This can be easily reproduced by modifying the CacheJdbcStoreExample.java in examples. This is happening under Ignite 1.30
Most likely you declared the factory or the listener as an anonymous class. Anonymous classes always contain reference to the parent class (LongCache in your case). So if the factory is serialized in the context of LongCache instance, this instance is also serialized. In case of static method this instance doesn't exist, therefore everything works.
I would recommend to convert anonymous classes to private static classes. This will give you more control on what is serialized.

Ninject Conditional injection problems

I have the following bindings declared
Bind<IDataSource>().To<DataSourceOne>();
Bind<ISettings>().To<DataSourceSettings>
.WhenInjectedInto<DataSourceOne>();
Bind<ISettings>().To<Settings>();
now I call
Kernel.Get<IDataSourc>();
Ninject correctly injects a DataSourceSettings, but I need to pass a constructor argument to Settings and DataSourceSettings based on data from a config file. so I've changed the IDataSouce binding as follows
Kernel.Bind<IDataSource>().To<DataSourceOne>()
.WithConstructorArgument("settings", Kernel.Get<ISettings>(
new ConstructorArgument("data", objectContainingConfigFileData)
)
);
in that case Ninject injects Settings class instead of DataSourceSettings class. I assume the problem is that the ISettings is getting resolved before it is injected into the DataSourceSettings class so Ninject does not use the binding I intended it to. Is there a way to get around this. I haven't found anything yet.
It should work if you define the constructor argument for the ISettings binding and not for the DataSource binding. Assuming you already know the object with the config file data in the module. Otherwise maybe a factory would be more appropriate.
kernel.Bind<IDataSource>().To<DataSourceOne>();
kernel.Bind<ISettings>().To<DataSourceSettings>()
.WhenInjectedInto<DataSourceOne>()
.WithConstructorArgument("data", objectContainingConfigFileData);
kernel.Bind<ISettings>().To<Settings>();

Ninject, Web API and MVC 4 Filter Binding disposing datacontext

I have an issue with my datacontext getting disposed every once in a while in one of my filters attached to my web api controllers. Is this the correct way to setup a filter for my Web API controllers and why does my datacontext get disposed sometimes?
The operation cannot be completed because the DbContext has been disposed.
Global.asax
GlobalConfiguration.Configuration.Filters
.Add(new ApiValidationFilter(kernel.Get<IApiAuthenticationService>()));
kernel.Bind<IDatabaseFactory>()
.To<DatabaseFactory>()
.InScope(q => HttpContext.Current ?? StandardScopeCallbacks.Thread(q));
ApiValidationFilter.cs
public class ApiValidationFilter : System.Web.Http.Filters.IActionFilter
{
private readonly IApiAuthenticationService _apiAuthenticationService;
public ApiValidationFilter(
IApiAuthenticationService apiAuthenticationService)
{
_apiAuthenticationService = apiAuthenticationService;
}
You should be using the Filter binding syntax, then Ninject will handle the the filter lifetime, and it will also handle the constructor injection of the filter.
https://github.com/ninject/ninject.web.mvc/wiki/Filter-configurations
I would also let Ninject handle managing the lifetime of the data conext as well, instead of using a factory.
kernel.Bind<MyContext>().ToSelf().InRequestScope();
Alternatively, if you want better testability you can derive your context from an interface and bind to that. The InRequestScope makes sure the context lives for the entire web request, and it will automatically get disposed when the request is done. You don't have to remember to do so, and there won't be any memory leaks by holding onto a request longer than a single request.
You can see an example here:
ASP.NET MVC 3 and Global Filter Injection
I eventually had to resort to the following, nothing worked.
var apiRepository = new ApiRepository(new DatabaseFactory());
var apiAuthenticationService = new ApiAuthenticationService(apiRepository, new UnitOfWork(new DatabaseFactory()), new ValidationProvider(null));