有人能告诉我如何在.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>();

以前使用 struct 映射时,将使用以下内容:

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(核心)内置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());
    
  • 看看replacing default service container个支持所需功能的人

Csharp相关问答推荐

MS Graph v5.42.0:在寻呼消息时更改页面大小

如何使用EF Core和.NET 8来upsert到具有多对多关系的表?

BlockingCollection T引发意外InvalidOperationException

LINQ to Entities中的加权平均值

如何将FindAll()与Nuget包Interop.UIAutomationClient一起使用

无法将生产环境的AppDbContext设置替换为用于集成测试的内存数据库

ASP.NET核心中的授权,如何在DbContext启动之前提供租用ID

CsvHelper在第二次迭代时抛出System.ObjectDisposedException

LINQ在GROUP BY和JOIN之后获取子列表

GMap.NET中的暗模式映射

创建在C++可执行文件中使用的C#DLL

如何在C#的Linq查询中将两行合并为一行

代码清理在插入的字符串中添加空格

如何强制一个过程在不可见的情况下开始?

当两个不同的实例用作任务时,正在释放实体框架DbContext实例

根据自定义默认策略使用角色和多个身份验证方案进行授权,但不适用于所有方案

Ms Graph v5.0如何获取所有SharePoint列表项

PInvoike InternetGetCookieEx2 返回错误 12006

try 使用 OpenSSL RSA 生成的密钥在 ASP .NET 应用程序中使用

复制构造函数不满足required属性