Auto load lazy property

I am trying to embed a business logic implementation in a basic web API controller. Somehow, the property in the base controller is always null .

Also how can I do a lazy injection?

Startups.cs

 public IServiceProvider ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); var containerBuilder = new ContainerBuilder(); containerBuilder.RegisterType<ViewBusinessLogic>().As<IViewBusinessLogic>(). PropertiesAutowired(); containerBuilder.Populate(services); var container = containerBuilder.Build(); return container.Resolve<IServiceProvider>(); } 

Interface, implementation and base controller:

 public interface IViewBusinessLogic { IEnumerable<dynamic> GetView(Guid viewId); } public class ViewBusinessLogic : BusinessLogic, IViewBusinessLogic { public IEnumerable<dynamic> GetView(Guid viewId) { return new List<dynamic> { new { Test = "Test1" }, new { Test = "Test2" } }; } } public abstract class BaseController : Controller { public IViewBusinessLogic ViewBusinessLogic { get; } } 
0
source share
1 answer

By default, controllers are not allowed by the DI framework. You need to add AddControllerAsServices so that they are enabled by the DI of your choice.

From this GitHub question :

Hi,

Maybe I'm wrong, but since I tested in depth (and checked the source code of Mvc), the controllers are not allowed from IServiceProvider , but only the constructor arguments from them are allowed with IServiceProvider .

Is it for design? I am very surprised. Because I use a different DI structure that supports property nesting. And I cannot use property nesting because Controller instances are not requested from IServiceProvider .

Have you added AddControllersAsServices to your startup ( https://github.com/aspnet/Mvc/blob/ab76f743f4ee537939b69bdb9f79bfca35398545/test/WebSites/ControllersFromServicesWebSite/Startup.cs#L37 )

The above example is cited for future reference.

 public void ConfigureServices(IServiceCollection services) { var builder = services .AddMvc() .ConfigureApplicationPartManager(manager => manager.ApplicationParts.Clear()) .AddApplicationPart(typeof(TimeScheduleController).GetTypeInfo().Assembly) .ConfigureApplicationPartManager(manager => { manager.ApplicationParts.Add(new TypesPart( typeof(AnotherController), typeof(ComponentFromServicesViewComponent), typeof(InServicesTagHelper))); manager.FeatureProviders.Add(new AssemblyMetadataReferenceFeatureProvider()); }) // This here is important .AddControllersAsServices() .AddViewComponentsAsServices() .AddTagHelpersAsServices(); services.AddTransient<QueryValueService>(); services.AddTransient<ValueService>(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); } 

Regarding the second part of your question: I don't think it is possible to have a lazy instance through an IoC container. For you, it's best to create a factory class and enter factory, not a specific service.

But usually you don't need a lazy instance anyway, creating services should be fast . If this is not the case, you are probably doing some funny things in the constructor (connecting somewhere or performing other lengthy operations), which is an anti-pattern.

+1
source

Source: https://habr.com/ru/post/1012857/


All Articles