我需要在Asp.Net WebAPI中的所有控制器/操作方法中公开单例共享对象。哪个是声明这样的全局静态对象的最佳位置,以便所有控制器/操作方法都可以访问它?
答案 0 :(得分:3)
您可以使用Lazy<T>
。这将确保线程安全:
public class Greeter
{
public static readonly Lazy<Greeter> Instance = new Lazy<Greeter>(() => new Greeter());
public Greeter()
{
// I am called once during the applications lifetime
}
public string Greet(string name)
{
return $"Hello {name}!";
}
}
然后在任何你喜欢的地方使用它:
public class GreetController : ApiController
{
public IHttpActionResult Get(string name)
{
var message = Greeter.Instance.Value.Greet(name);
return Ok(message);
}
}
答案 1 :(得分:2)
“最佳”方式是使用DI(依赖注入)容器,并将单例注入需要它的控制器中。我将举例说明Ninject,因为这就是我使用的,但您可以轻松地将代码调整到您决定使用的任何容器。
<强> NinjectWebCommon.cs 强>
kernel.Bind<MySingleton>().ToSelf().InSingletonScope();
<强>控制器(一个或多个)强>
public class FooController : ApiController
{
protected readonly MySingleton mySingleton;
public FooController(MySingleton mySingleton)
{
this.mySingleton = mySingleton;
}
}
换句话说,DI容器管理单例。您的控制器接受单例作为构造函数参数,并将其设置在控制器上。 DI容器然后将单例注入控制器,然后您可以像控制器的任何其他成员一样自由地使用它。
答案 2 :(得分:1)
您可以在WebApiApplication(Global.asax.cs)中声明变量,并在所有带有代码的控制器中使用它:
talend.project
但对我而言,这不是最好的方法,因为你会在初始化和设置值方面获得开销,而且看起来像是一些架构问题。
为什么需要全局对象? 如果它有些函数只是声明新的父控制器并在其中声明这个函数。 如果您需要只读数据 - 请将其放入web.cofig。