Added GetRegisteredServices
Added GetRegisteredServices methods to expose the list of ServiceRegistrations available for a given type. This makes it possible to create a JsonContractResolver which resolves to the LightInject supplied type. Also added to mock.
Hi @alandraper
I am just wondering why IServiceRegistry.AvailableServices wouldn't be sufficient here? 😀
It would, but then I have to look through all registrations every time, or build up a dictionary for lookups, which would duplicate the dictionary you already have.
I'm just trying to understand this example https://www.newtonsoft.com/json/help/html/DeserializeWithDependencyInjection.htm
What is actually going on here. Do you have a simpler example of what you are trying to do?
Some of the types are not even in the example 😀
Sure. I'm trying to create a Newtonsoft.Json.Serialization.IContractResolver which uses LightInject to create objects.
This way, when I call JsonConvert.DeserializeObject<IFoo>(json), it will use the LightInject container for object resolution.
Here's the implementation I'm working with now, which seems to be working.
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
public JsonContractResolver(LightInject.IServiceContainer container)
{
this.Container = container;
}
private IServiceContainer Container { get; }
protected override JsonObjectContract CreateObjectContract(Type objectType)
{
var services = this.Container.GetRegisteredServices(objectType);
if (services.Any())
{
var resultType = services.FirstOrDefault().ImplementingType;
JsonObjectContract contract = base.CreateObjectContract(resultType);
contract.DefaultCreator = () => this.Container.GetInstance(objectType);
return contract;
}
return base.CreateObjectContract(objectType);
}
}
And here's how it's used:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects,
ContractResolver = new JsonContractResolver(container),
};
This is also useful for implementing an easy IsRegistered(Type) method for a given service type.
Any chance of this being accepted? Or anything I can do to make it more palatable? It's hard to work from my own codebase when Umbraco references the nuget package, and running two dependency injectors on the same site seems like a recipe for trouble.
Are there any plans to move this foward? I know its a nice to have, but for the reasons mentioned, its better to use the internal dictionary instead of creating a new one. For example in my use case I wanted to retrieve the implementing type from the handler (after being decorated it returns an instance of the decorator). And maybe this could be available on IServiceRegistry instead of IServiceFactory? Or both?