Singleton service visible from the classes - asp.net

I have a singleton service class
public class Globals
{
public string serverURL { get; set; } = "";
public string hostURL { get; set; } = "";
}
and I have registered it in the Main function:
builder.Services.AddSingleton<Services.Globals>();
anyway I would like to access it from the rest of the Classes in the project, not only the razor pages.
For instance I have a class inside a PCL library:
public class MyStuff
{
public MyStuff()
{
- How do I access Globals in here?!
}
public void MyStuffMethod()
{
- How do I access Globals in here?!
}
}
How to access a Singleton object from the rest classes in the project ?

Access like this, you just need to add a parameter in constructor of class.
public class HomeController : Controller
{
private Globals _globals;
public HomeController(Globals globals)
{
_globals = globals;
}
}

Related

Controller cannot reach Controller in other project because of constructor ASP:NET Core

I'm new to ASP.NET Core and I'm trying to solve this problem for a week now.
I have a solution with two projects.
And when I start the porject the browser just says:
InvalidOperationException: Unable to resolve service for type 'TSM_Programm.Data.TSMContext' while attempting to activate 'TSM_Programm.Controllers.ResourcesController'.
The first part of the solution is my API-Layer that passes data to a user (currently via postman).
The second project is my Data Access Layer.
This Layer contains several Controllers, all of them using the same constructor, which is the following:
public TSMContext _context;
public ResourcesController(TSMContext context)
{
_context = context;
}
The TSMContext Class is the following:
namespace TSM_Programm.Data
{
public class TSMContext : DbContext
{
public TSMContext(DbContextOptions<TSMContext> options)
: base(options)
{
}
public DbSet<Resource> Resources { get; set; }
public DbSet<Parameter> Parameters { get; set; }
public DbSet<ResourceToParameter> ResourceToParameters { get; set; }
public DbSet<Reservation> Reservations { get; set; }
}
So far so god, but when I am trying to start the program the controllerof the API-Layer does not seem to be able to handle the constructor.
This is my API-Conrtoller:
namespace TSM_API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class APIController : ControllerBase //Base Class without View Support
{
//Troublemaker
public ResourcesController _resources;
public ParametersController _parameters;
public ReservationsController _reservations;
public APIController(ResourcesController resources, ParametersController parameters, ReservationsController reservations)
{
_resources = resources;
_parameters = parameters;
_reservations = reservations;
}
//Function to check if controller works
//GET: api/API
[HttpGet]
public IEnumerable<string> Get()
{
// ResourcesController controller = new ResourcesController();
return new string[] { "value1", "value2" };
}
The API-Controller was not able to use its own constructors, that's why I changed the Startup.cs.
namespace TSM_API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMvc().AddApplicationPart(typeof(ResourcesController).Assembly).AddControllersAsServices();
services.AddMvc().AddApplicationPart(typeof(ParametersController).Assembly).AddControllersAsServices();
services.AddMvc().AddApplicationPart(typeof(ReservationsController).Assembly).AddControllersAsServices();
services.AddMvc().AddApplicationPart(typeof(TSMContext).Assembly).AddControllersAsServices();
}
I'm simply out of ideas on how to solve the problem, since I can't add the TSMContext class a service.
Any idea how to solve it?
Thank you.
I see you have not registered your dbcontext as a dependency injection. Your issue might be due to ResourceController trying to access _context as a DI but it is not registered. To use the context as a dependency injection, register it in the startup.cs as following.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TSMContext>(options => options.UseSqlServer(Configuration.GetConnectionString("YOUR_CONNECTION_STRING")));
//If you have any services that should be used as DI, then they also must be registered as like this
services.AddScoped<Interface, Class>(); //Interface refer to the service interface while class is the actual service you will use.
}

What is the namespace for IService interface?

I am learning ServiceStack and developing simple demo for helloworld, but could not find namespace for ISservice interface, my code as per below:
public class Hello
{
public string name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
public class HelloService : **IService**<Hello>
{
public object Execute(Hello request)
{
return new HelloResponse { Result = "Hello" + request.name };
}
}
public class HelloAppHost : AppHostBase
{
public HelloAppHost() : base("Hello Web Services", typeof(HelloService).Assembly) { }
public override void Configure(Funq.Container container)
{
Routes.Add<Hello>("/hello")
.Add<Hello>("/hello/{Name}");
}
}
Can anyone please tell me what namespace or DLL I need to add for IService interface?
ServiceStack's IService<T> is in the ServiceStack.ServiceHost namespace which lives in the ServiceStack.Interfaces.dll, why here's the class:
https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.Interfaces/ServiceHost/IService.cs
Note: If you're just starting out, it's probably better to inherit from ServiceStack.ServiceInterface.ServiceBase<T> and override the Run() method which is a useful base class that provides things like auto exception handling for you.
If you want to be able run different code for different HTTP Verbs e.g GET/POST/PUT/DELETE (i.e. creating REST web services) than you want to inherit from RestServiceBase instead and override its OnGet/OnPost/OnPut/OnDelete methods.

Registering Composite Classes in Unity

in my implementation, I have an interface as: ICachingManager. I've got now one implementation. I also created a manager class as:
public class CachingManager
{
#region Members
private ICachingManager service;
#endregion
#region Constructors
public CachingManager(ICachingManager service)
{
this.service = service;
}
#endregion
#region Public Methods
public void EnCache<T>(string key, T value)
{
this.service.EnCache<T>(key, value);
}
public T DeCache<T>(string key)
{
return this.service.DeCache<T>(key);
}
#endregion
}
In case I had one implementation, then I can easily register the CachingManager class with Unity, automatically Unity resolves and injects the ICachingManager.
In case I had more than one implementation using named types, then how can I can make use of Unity? Do I need to make use of an Abstract Factory to decide on which named type to initialize?
Is it a good idea to make use of such a composite class or use directly implementations of the interface with Abstract Factory?
You don't have to create an abstract factory. You can inject a given named implementation:
public class MyClient
{
[Dependency("NamedManager")]
public ICachingManager CachingManager { get; set; }
// or in the constructor
public MyClient([Dependency("NamedManager")] ICachingManager cachingManager) {
// ...
}
}
or you can configure the container to do the same thing:
public class MyClient
{
public MyClient(ICachingManager cachingManager) {
// ...
}
}
...
void ContainerBuilder() {
...
Container.RegisterType<MyClient>(
new InjectionConstructor(
new ResolvedParameter<ICachingManager>("NamedManager")));
...
}

Unity 1.2 Dependency injection of internal types

I have a facade in a library that exposes some complex functionality through a simple interface. My question is how do I do dependency injection for the internal types used in the facade. Let's say my C# library code looks like -
public class XYZfacade:IFacade
{
[Dependency]
internal IType1 type1
{
get;
set;
}
[Dependency]
internal IType2 type2
{
get;
set;
}
public string SomeFunction()
{
return type1.someString();
}
}
internal class TypeA
{
....
}
internal class TypeB
{
....
}
And my website code is like -
IUnityContainer container = new UnityContainer();
container.RegisterType<IType1, TypeA>();
container.RegisterType<IType2, TypeB>();
container.RegisterType<IFacade, XYZFacade>();
...
...
IFacade facade = container.Resolve<IFacade>();
Here facade.SomeFunction() throws an exception because facade.type1 and facade.type2 are null. Any help is appreciated.
Injecting internal classes is not a recommended practice.
I'd create a public factory class in the assembly which the internal implementations are declared which can be used to instantiate those types:
public class FactoryClass
{
public IType1 FirstDependency
{
get
{
return new Type1();
}
}
public IType2 SecondDependency
{
get
{
return new Type2();
}
}
}
And the dependency in XYZFacade would be with the FactoryClass class:
public class XYZfacade:IFacade
{
[Dependency]
public FactoryClass Factory
{
get;
set;
}
}
If you want to make it testable create an interface for the FactoryClass.
If the container creation code is outside the assembly of the internal types, Unity can't see and create them and thus can't inject the dependecies.

Ninject giving NullReferenceException

I'm using asp.net MVC 2 and Ninject 2.
The setup is very simple.
Controller calls service that calls repository.
In my controller I use inject to instantiate the service classes with no problem. But the service classes don't instantiate the repositories, giving me NullReferenceException.
public class BaseController : Controller
{
[Inject]
public IRoundService roundService { get; set; }
}
This works. But then this does not...
public class BaseService
{
[Inject]
public IRoundRepository roundRepository { get; set; }
}
Giving a NullReferenceException, when I try to use the roundRepository in my RoundService class.
IList<Round> rounds = roundRepository.GetRounds( );
Module classes -
public class ServiceModule : NinjectModule
{
public override void Load( )
{
Bind<IRoundService>( ).To<RoundService>( ).InRequestScope( );
}
}
public class RepositoryModule : NinjectModule
{
public override void Load( )
{
Bind<IRoundRepository>( ).To<RoundRepository>( ).InRequestScope( );
}
}
In global.axax.cs
protected override IKernel CreateKernel( )
{
return new StandardKernel( new ServiceModule( ),
new RepositoryModule( ) );
}
Have you thought about using constructor injection?
That's how I do my dependency injection with Ninject 2 & ASP.NET MVC 2 and it works all the way down the chain from controller -> service -> repository & beyond.
It also makes sense to me to have the dependencies in the constructor for your object. It makes these dependencies highly visible and obvious to any other object that has to instantiate it. Otherwise you may end up with null reference exceptions... kinda like you have here.
HTHs,
Charles
EDIT: Showing base class injection through constructors in response to the comments.
public class BaseService
{
public IRoundRepository RoundRepo { get; private set; }
public BaseService(IRoundRepository roundRepo)
{
RoundRepo = roundRepo;
}
}
public class SquareService : BaseService
{
public ISquareRepository SquareRepo { get; private set; }
public SquareService(ISquareRepository squareRepo, IRoundRepository roundRepo)
: base(roundRepo)
{
SquareRepo = squareRepo;
}
}
This is just my way of doing things... someone else may have a different idea / opinion.

Resources