I need to expose a singleton shared object across all controllers/action methods in Asp.Net WebAPI. Which is the best place to declare such global static objects so that all co
You can declare variable inside your WebApiApplication (Global.asax.cs) and use it in all controllers with code:
var globalValue = (HttpContext.Current.ApplicationInstance as WebApiApplication).GlobalVariableName;
But as for me it's not the best way, because you'll get overhead with initialization and setting value and also it looks like some architecture issue.
Why do you need global object? If it some function just declare new parent controller and declare this function in it. If you need read only data - put it into web.cofig.
The "best" way is to use a DI (dependency injection) container, and inject the singleton into the controllers that need it. I'll give an example with Ninject, since that's what I use, but you can easily adapt the code to whatever container you decide on.
NinjectWebCommon.cs
kernel.Bind<MySingleton>().ToSelf().InSingletonScope();
Controller(s)
public class FooController : ApiController
{
protected readonly MySingleton mySingleton;
public FooController(MySingleton mySingleton)
{
this.mySingleton = mySingleton;
}
}
In other words, the DI container manages the singleton. Your controller(s) accept the singleton as a constructor param, and set it on the controller. The DI container will then inject the singleton into the controller, and you can then use it freely as you would any other member of the controller.
You can use Lazy<T>
. This will ensure thread safety:
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}!";
}
}
Then use this wherever you like:
public class GreetController : ApiController
{
public IHttpActionResult Get(string name)
{
var message = Greeter.Instance.Value.Greet(name);
return Ok(message);
}
}