有人可以告诉我如何在 .NET 8 中注册以下工厂吗?:
public class DefaultViewFactory : IViewFactory
{
private readonly IServiceProvider _serviceProvider;
public DefaultViewFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public TView CreateView<TView>()
{
var service = _serviceProvider.GetService<IViewBuilder<TView>>();
return service != null ? service.Build() : Activator.CreateInstance<TView>();
}
public TView CreateView<TInput, TView>(TInput input)
{
var service = _serviceProvider.GetService<IViewBuilder<TInput, TView>>();
if (service != null)
{
return service.Build(input);
}
return (TView)Activator.CreateInstance(typeof(TView), input)!;
}
}
我已将以下代码添加到 Program.cs 文件中:
serviceCollection.AddTransient<IViewFactory, DefaultViewFactory>();
以前使用 StructureMap,会使用以下内容:
configurationExpression.Scan(assemblyScanner =>
{
assemblyScanner.TheCallingAssembly();
assemblyScanner.ConnectImplementationsToTypesClosing(typeof(IViewBuilder<>));
assemblyScanner.ConnectImplementationsToTypesClosing(typeof(IViewBuilder<,>));
})
有人可以建议替代实施吗?
我添加了IViewBuilder以供参考:
public interface IViewBuilder<out TView>
{
TView Build();
}
public interface IViewBuilder<in TInput, out TView>
{
TView Build(TInput input);
}
.NET(Core)内置DI不支持程序集扫描和匹配封闭泛型类型。
如果您有一个开放通用实现,那么您可以将其注册为开放通用:
services.AddTransient(typeof(IViewBuilder<>), typeof(SomeGenericViewBuilder<>));
services.AddTransient(typeof(IViewBuilder<,>), typeof(SomeGenericViewBuilder<,>));
如果您有不同的类型实现接口,那么您可以:
手动注册它们:
services.AddTransient(typeof(IViewBuilder<SomeView>), typeof(SomeViewBuilder));
// ...
自己编写汇编扫描代码(使用反射API)
Scrutor
(未测试):
var collection = new ServiceCollection();
collection.Scan(scan => scan
// We start out with all types in the assembly
.FromAssemblyOf<ViewBuildersAssemblyTypeLandmark>()
// Generic interfaces are also supported too
.AddClasses(classes => classes.AssignableTo(typeof(IViewBuilder<>)))
.AsImplementedInterfaces()
// And you scan generics with multiple type parameters
.AddClasses(classes => classes.AssignableTo(typeof(IViewBuilder<,>)))
.AsImplementedInterfaces());