代码之家  ›  专栏  ›  技术社区  ›  David Liang

ServiceStack IAppSettings未就绪,如果在构造函数中使用,将导致空引用异常

  •  2
  • David Liang  · 技术社区  · 4 年前

    看起来像是 IAppSettings 在构造器中,IoC尚未准备好实施。

    在详细介绍之前,我已经读过类似的问题:

    两人的回答都是@mythz,他无法复制它。

    从医生那里

    “ServiceStack制造 AppSettings 一级属性,默认为查看。NET的应用程序/网络。配置文件“: https://docs.servicestack.net/appsettings#first-class-appsettings

    还有 default IoC registration already 在Funq给你 应用设置 当你要求 IAppSettings :

    enter image description here

    我所拥有的

    我所有的代码都在回购协议中: https://github.com/davidliang2008/MvcWithServiceStack

    演示应用程序只是一个ASP。NET MVC应用程序(.NET 4.8),该应用程序使用您可以获得的最简单的模板构建,并安装了ServiceStack(5.12.0):

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            ...
            new AppHost().Init();
        }
    }
    
    public class AppHost : AppHostBase
    {
        public AppHost() : base("MvcWithServiceStack", typeof(ServiceBase).Assembly) { }
    
        public override void Configure(Container container)
        {
            SetConfig(new HostConfig
            {
                HandlerFactoryPath = "api";
            }
    
            ControllerBuilder.Current.SetControllerFactory(new FunqControllerFactory(container));
        }
    }
    

    然后我有一个ServiceStack服务的基类,以及一个 HelloService 只是为了演示:

    public abstract class ServiceBase : Service { }
    
    public class HelloService : ServiceBase
    {
        public IAppSettings AppSettings { get; set; }
    
        public object Get(HelloRequest request)
        {
            return new HelloResponse
            {
                Result = $"Hello, { request.Name }! Your custom value is { AppSettings.Get<string>("custom") }."
            };
        }
    }
    
    [Route("/hello/{name}")]
    public class HelloRequest : IReturn<HelloResponse>
    {
        public string Name { get; set; }
    }
    
    public class HelloResponse
    {
        public string Result { get; set; }
    }
    

    什么有效

    当你不使用 IAppSettings 在构造函数中,是否在 HelloService 或者它的基础阶级 ServiceBase ,一切顺利。

    将项目克隆到本地时,如果导航到 /api/hello/{your-name} ,您将看到它的响应将能够从web获取自定义值。配置:

    // TODO: attach screenshot

    什么不起作用

    当你试图得到 IAppSettings 并在构造函数中使用一些应用程序设置值初始化其他内容-无论是在子类还是基类中, IAppSettings 将无法从IoC获得实现,并导致空引用异常:

    public abstract class ServiceBase : Service
    {
        public IAppSettings AppSettings { get; set; }
    
        public ServiceBase()
        {
            // AppSettings would be NULL
            var test = AppSettings.Get<string>("custom");
        }
    }
    

    public class HelloService : ServiceBase
    {
        public HelloService()
        {
            // AppSettings would be NULL
            var test = AppSettings.Get<string>("custom");
        }
    }
    

    // TODO: attach screenshots

    1 回复  |  直到 4 年前
        1
  •  0
  •   mythz    4 年前

    不能在构造函数中使用任何属性依赖项,因为只有在创建类并运行构造函数后才能注入属性。

    您只能使用构造函数注入在构造函数中访问它,例如:

    public class HelloService : ServiceBase
    {
        public HelloService(IAppSettings appSettings)
        {
            var test = appSettings.Get<string>("custom");
        }
    }
    

    或者通过singleton访问依赖项:

    public class HelloService : ServiceBase
    {
        public HelloService()
        {
            var test = HostContext.AppSettings.Get<string>("custom");
        }
    }