Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How is a Factory class registered in .NET 8?

Could someone please show me how I register the following Factory in .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)!;
    }
}

I’ve added the following code to the Program.cs file:

serviceCollection.AddTransient<IViewFactory, DefaultViewFactory>();

Previously using StructureMap, the following would be used:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

configurationExpression.Scan(assemblyScanner =>
{
    assemblyScanner.TheCallingAssembly();
    assemblyScanner.ConnectImplementationsToTypesClosing(typeof(IViewBuilder<>));
    assemblyScanner.ConnectImplementationsToTypesClosing(typeof(IViewBuilder<,>));
})

Could someone please advise an alternative implementation?

I have added the IViewBuilder for reference:

public interface IViewBuilder<out TView>
{
    TView Build();
}

public interface IViewBuilder<in TInput, out TView>
{
    TView Build(TInput input);
}

>Solution :

.NET (Core) build-in DI does not support assembly scanning and matching closed generic types.

If you have a single open generic implementation then you can register it as open generic:

services.AddTransient(typeof(IViewBuilder<>), typeof(SomeGenericViewBuilder<>));
services.AddTransient(typeof(IViewBuilder<,>), typeof(SomeGenericViewBuilder<,>));

If you have different types implementing the interface then you can:

  • Register them manually:

    services.AddTransient(typeof(IViewBuilder<SomeView>), typeof(SomeViewBuilder));
    // ...
    
  • Write assembly scanning code yourself (using reflection APIs)

  • Use some library like Scrutor (not tested):

    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());
    
  • Look into replacing default service container with one which supports needed functionality

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading