4

I have a .NET Core MVC application (C#), which uses C++ libraries(SWIG). In the C# I need to create an instance of one of the classes, preset its callback and keep it alive when the server is running. Using this callback I get data from the C++. I've tried to store the object in the session, but I can store only values there:

HttpContext.Session.Set(key, value);

Also tried to define it on Startup, but the object is disposed after initialization. What is the best solution in this case?

Note: In the callback function I'm publishing the data with SignalR.

EvilDr
  • 8,943
  • 14
  • 73
  • 133
I.Manev
  • 709
  • 7
  • 23
  • I think you can use in-mem cache (https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory) – Kien Chu Mar 27 '18 at 09:42
  • Have you considered a static field? –  Mar 27 '18 at 09:55
  • You can create a service that returns the object and inject it with singleton lifecycle. Check here https://stackoverflow.com/questions/38138100/what-is-the-difference-between-services-addtransient-service-addscope-and-servi?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – M Bakardzhiev Mar 27 '18 at 10:00
  • @MBakardzhiev The `services.addSingleton` doesn't work, neither the scoped variable, I already tried that. @buffjape Do you mean static field in the controller? – I.Manev Mar 27 '18 at 10:02
  • Create a static class with a static constructor. The static constructor will only be run the first time the type is referenced within a run of the application. Give the class static fields / methods that return the c++ data. – Glubus Mar 27 '18 at 10:27
  • Possible duplicate of [AddTransient, AddScoped and AddSingleton Services Differences?](https://stackoverflow.com/questions/38138100/addtransient-addscoped-and-addsingleton-services-differences) – Mikael Dúi Bolinder May 20 '19 at 14:08

2 Answers2

4

Since you're using ASP.NET Core, use the built-in Service Manager.

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<SwiggStuff>();
}

To later get that service, use the RequestServices of the HttpContext.

HttpContext.RequestServices.GetService<SwiggStuff>();

Even better, make SwiggStuff implement ISwiggStuff and register it using AddSingleton<ISwiggStuff, SwiggStuff>() and then get it using GetService<ISwiggStuff>(). This allows for injection of a FakeSwiggStuff when you do Unit Testing.

Mikael Dúi Bolinder
  • 2,080
  • 2
  • 19
  • 44
0

Create this object somewhere in a domain namespace.

public static class SwiggStuff {
     public static SwigObject { get; }

     static SwiggStuff() {
          SwigObject = new SwigObject();
     }
}

Now you can access the swigobject anywhere you reference the namespace this object lives in, it will not be disposed untill the program terminates.

EDIT (year after posting): Even though this works and is perfectly fine, it's not really the way to go in a .NET Core application. NET Core provide their own way to manage scoped instances and singletons.

If you're trying to use a singleton in the context of a .NET Core application, please look at the answer below this one.

Glubus
  • 2,819
  • 1
  • 12
  • 26
  • That's right! For some reason, I was trying to extend the Swig class instead of just creating an instance of it as a static field. Thanks! – I.Manev Mar 27 '18 at 11:02
  • 1
    This can be used in any C# project, however this question is for ASP.NET Core which has [its own way](https://stackoverflow.com/a/56222353/1275774) of managing singletons. – Mikael Dúi Bolinder May 20 '19 at 14:05
  • Yea you're right. I would also use the .NET Core framework for this and my answer would be different today. However, there's still some places in your application where it might not be necessary to use the .NET Core Framework, e.g. domain layer. At the same time there is not really a reason not to... Future readers should use the other answer, not this one. – Glubus May 20 '19 at 14:25