.NET 8 中工厂类是如何注册的?

问题描述 投票:0回答:1

有人可以告诉我如何在 .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);
}
c# dependency-injection .net-8.0
1个回答
1
投票

.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());
    
  • 研究用支持所需功能的容器替换默认服务容器

© www.soinside.com 2019 - 2024. All rights reserved.