I would like to use a JsonConverter<> which has dependency, and that dependency can not be a singleton, instead should be resolve as scoped...
I have to configure my System.Text.JsonConverter in Startup, so I must provide the JsonSerializaionOptions along with my JsonConverter<> instance in Startup. I can live together the JsonConverter<> as singleton, I instantiate myself, but how can I inject its scoped dependencies?
The only horrible thing comes in my mind to have a IServiceProvider property, and some other logic later (middleware?) checks if that property is initialized and initializes it. So in the actual Read and Write methods of the JsonConverter<> can access to the scoped dependency via the IServiceProvider.
This sounds sooo errorprone and smells, once because of timing (what is the actual conversion occurs before the property injection), but my main concern is the concurrency, having this JsonConverter<> a singleton by design, so the very same IServiceProvider instance in the injected property will be used concurrently by all the web app threads...
What am I missing here?
Is having a scoped dependency for a JsonConverter<> smells?
Is there a way to not instantiate the JsonConverter<> in Startup? (yes I know I could instantiate JsonSerializerOptions and do manually the serialization with JsonConverter), but this way I can not use many built in json support of ASP.NET Core
Related
I'm trying to find how I can use dependency injection to inject a ConnectionString or a custom AppSetting object so far i end up in the startup using
services.Configure<IConnectionStrings>(Configuration.GetSection("MyConnection"));
example layer
Web MVC application
Business Logic (class library)
Repository (class library)
DAL (class library)
Model (class library)
where web see only Business logic and so on, on model is available for all.
In the DAL project I have an object that takes care of connecting and running queries against my database (CDbTools object).
Now, how can I inject directly into CDbTools without going from controller down to DAL.
Thank you.
Dependency injection definitely takes a little getting used to, and you won't be creating objects quite the way you're used to. What you want to do is first is modify your CDbTools to take the injected strings.
public CDbTools(IConnectionStrings strings)
{
_connectionString = strings
}
The next step will be to actually inject the CDbTools into the classes that need it as well. First, register it in the startup.
services.AddScoped<CDbTools>();
You'll need to follow this up the chain. Don't think of it as passing the objects from the top level down - that will mess up your separation of concerns. Each layer has the lower layer injected in. This won't just get you the injection of your string you are looking for. It will let you mock things easier, swap layers easier, and a slew of other benefits.
I believe you should add this to your ConfigureServices method:
services.Configure<CustomSettings>(settings =>
{
Configuration.GetSection("CustomSettings").Bind(settings);
});
Where services is your IServiceCollection object and CustomSettings is your custom configuration class that you want to inject. That custom object should map to your settings fields.
Hope this helps!
In building my current (first) Windows Phone app it requires me to create a Windows Runtime Component to achieve the functionality I require. In order for this setup to work and not duplicate a lot of code from my PCLs into the task class itself, I wanted to use the MMVMCross IOC that I am already using throughout the application.
Unfortunately, the Background Task (IBackgroundTask) is executed in an entirely different process. Trying to utilize the IOC via Mvx.Resolve throws a NullReferenceException. I cannot figure out how to initialize the IOC as the standard "setup.cs" method does not work in the Runtime Component.
I do not need the entire MVVMCross stack for this -- just the IOC.
Thank you.
I finally figured it out. I have to re-register on the background task, but to initialize you would call the basic initialize method on the simple IOC container:
Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.Initialize();
Plugins were a problem, as the standard plugin mechanism is not available, but you can manually register the interfaces such as this:
Mvx.LazyConstructAndRegisterSingleton<IMvxFileStore>(() => new MvxWindowsCommonBlockingFileStore());
Of course, you can still register your other types and interfaces as you normally would.
I wonder if it's possible to get an instance of the JAX-RS Application a resource is attached on. Ideally a way that isn't dependent to a specific implementation. For example using dependency injection...
Thanks very much for your help,
Thierry
As stated in The Spec
5.2.1 Application
The instance of the application-supplied Application subclass can be injected into a class field or method parameter using the #Context annotation. Access to the Application subclass instance allows configuration information to be centralized in that class. Note that this cannot be injected into the Application subclass itself since this would create a circular dependency.
but from I've experienced, it will most likely not be the actual instance, but a proxy. Also if you're looking to alter anything on it, I'm not sure it's possible. It might be read-only.
I am learning to use dependency injection with ninject. Most of the properties and methods are fairly intuitive, one that has me though is Kernel.Inject(instance);
What does the Inject method actually do as it doesn't return anything. I've looked around but search for a method called inject on a dependency injection container is a nightmare, I can't find any references to the method specifically.
Kernel.Inject(instance) will inject dependencies into an already existing object.
That's why it returns void because it takes the parameter object instance and starts to investigate it's methods and property setters looking for the [Inject] attribute. Then it will call them with the resolved instances of their parameter types. (this is called Method or Property injection)
So when contructor injection is not enoughpossible you can Kernel.Inject to fill in your dependencies for a given instance.
You can read more about this here: Ninject Injection Patterns
We've begun using Dependency Injection recently, and we've chosen Ninject 2 (for now) as our IoC Container. As I refactor our solution to incorporate DI principles, I've run into something that bugs me a little, and I'm wondering if there's an easy way to get around it.
For our data layer, we have a whole bunch of data-access classes that inherit the same generic class (EntityMapper). While in the past we've always constructed a new instance of these classes when we needed one, they really could all be changed into Singletons. We've overridden ObjectDataSource to use Ninject to instantiate its data-access object, so any time we create an ObjectDataSource that points to one of our EntityMapper classes, Ninject will use its default self-binding strategy to inject the necessary dependencies. Since there are so many of these classes, we'd rather not have to create an explicit binding for each of our EntityMapper classes, and we'd rather not have to put a special attribute on every one of them either. However, I would like to be able to instruct Ninject to make any instance of EntityMapper into a singleton class. Something like this:
Bind(t => typeof(IEntityMapper).IsAssignableFrom(t)).InSingletonScope();
Is there any way to do this?
You can use the conventions extension to do the following
var kernel = new StandardKernel();
kernel.Scan( x=>
{
x.FromAssemblyContaining<MyEntityMapper>();
x.FromCallingAssembly();
x.WhereTypeInheritsFrom<IEntityMapper>();
x.InSingletonScope();
} );