如何为泛型接口IFoo<TBar>构造System.Type并通过DI解析实例
Solution for Resolving IFoo via Dependency Injection
Alright, let's break down how to implement the CreateFooUsingBarType method correctly. The core challenge here is dynamically constructing the generic IFoo<TBar> type from the incoming barType parameter, then resolving it from your DI container.
Step 1: Construct the Generic Interface Type
First, we need to get the open generic type definition for IFoo<>, then combine it with the provided barType to create the closed generic type we need.
Step 2: Resolve the Instance from DI
Once we have the closed generic type, we can use your DI scope to resolve an instance of that type, then cast it to the non-generic IFoo interface (since that's the return type of the method).
Here's the complete implementation with explanations:
public IFoo CreateFooUsingBarType(Type barType) { var iocScope = GetScope(); // 1. Get the open generic definition of IFoo<> Type openGenericFooType = typeof(IFoo<>); // 2. Create the closed generic type: IFoo<TBar> where TBar is barType Type closedGenericFooType = openGenericFooType.MakeGenericType(barType); // 3. Resolve the instance from the DI container object resolvedInstance = iocScope.ServiceProvider.GetService(closedGenericFooType); // 4. Cast to the non-generic IFoo interface (since our method returns IFoo) if (resolvedInstance is not IFoo fooInstance) { throw new InvalidOperationException($"No valid IFoo implementation registered for bar type {barType.FullName}"); } return fooInstance; }
Key Notes:
- Open vs Closed Generic Types:
typeof(IFoo<>)gives us the open generic type (without a type argument), whileMakeGenericType(barType)turns it into a closed generic type specific to yourbarType. - DI Resolution: We use
GetServicehere (you could also useGetRequiredServiceif you want the container to throw immediately if the type isn't registered) to fetch the instance. - Type Safety Check: The cast check ensures we don't return something that doesn't implement the non-generic
IFoointerface, which prevents runtime type errors later.
Optional Enhancements:
- If you want to handle cases where the type isn't registered gracefully, you can return
nullinstead of throwing (but make sure your method's contract allows for that). - Add validation upfront to ensure
barTypeis notnullor an invalid type (e.g., abstract, interface if your implementations require concrete types).
内容的提问来源于stack exchange,提问作者AdamStone
相关产品推荐
相关产品推荐

