Ok, the Title already sounds a bit silly, but I don't even know how to describe this better. So let's try to outline the problem.
What I've figured out so far is the following, which is working:
Given I have an interface like that
public interface ISomeService {}
then I can dynamically add the service with it's implementation like that
var vendorService = assembly?.GetType($"{vendor}.Services.{vendor}Service");
// null-check here
services.TryAddSingleton<ISomeService>(_ =>
(ISomeService) Activator.CreateInstance(vendorService, _config)!);
(I need to do this, because at Compile-time I do not yet know which service will be finally loaded. This information is coming from a command-line-argument)
So far so good...
Now I have another Service that looks like this:
public interface IInformationService<T>
{
public string? Serialize(T vendorInformation, bool isFile);
public T Deserialize(string? filename = null);
}
In this case I don't know how to add the Service to a collection since...
var vendorInfoService = assembly?.GetType($"{vendor}.Services.InformationService<{vendor}>");
// null-check here
services.TryAddSingleton<IInformationService< [???] >>(_ =>
(IInformationService< [???] >) Activator.CreateInstance(vendorInfoService, _config)!);
... I don't know how to pass T down, which is not known until it is clear what vendor is.
So given the vendor (which is not known at compile-time) is "Foo" then the actual Type of the above vendorService would be FooService, the Information-Service would be InformationService<FooModel>.
But I'm really not sure how to implement it.
Maybe you can help me out. Thanks in advance :)
That should be possible like this:
or, if you want to get rid of the Activator, just like this:
The problem here is, that you don't get any information about the "T", so you somehow have to make sure that for every T you try to inject in one of your services, there is a binding that matches said T.
A better way would most likely be to reiterate over this and define a service interface without the generic and design an
IVendorInformationModelinstead, which is passed toSerializeor provided byDeserialize.