另外我怎么做懒人注射?
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>(); }
接口,实现和基本控制器:
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; } }
解决方法
Hi,
Maybe I’m wrong but as I tested deeply (and checked Mvc source code),Controllers are not resolved from
IServiceProvider
,but only constructor arguments of them are resolved fromIServiceProvider
.Is that by design? I’m very suprised. Because,I’m using a different DI framework which supports property injection. And I can not use property injection since Controller instances are not requested from
IServiceProvider
.
您是否在Startup中添加了AddControllersAsServices(https://github.com/aspnet/Mvc/blob/ab76f743f4ee537939b69bdb9f79bfca35398545/test/WebSites/ControllersFromServicesWebSite/Startup.cs#L37)以上示例引用以供将来参考.
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>(); }至于你问题的第二部分:我认为根本不可能通过IoC容器进行延迟实例化.最适合您的是创建工厂类并注入工厂而不是具体服务.
但通常你不需要懒惰的实例化,服务的实例化应该很快.如果不是,你可能在构造函数中做一些时髦的东西(连接某个地方,或做其他长时间运行的操作),这是一种反模式.