In 2 different ASP.Net Core API Controllers, how to ensure same endpoints are defined? - asp.net

I have a requirement to have 2 data api's both of which should have same methods or endpoints to be implemented.
For example, we can have an interface to make sure, two classes will have same functions. Otherworldly, you define the contract.
public interface ITest
{
void Foo();
}
public class Test : ITest
{
public void Foo()
{
// Some logic
}
}
public class OtherTest : ITest
{
public void Foo()
{
// Some other logic
}
}
Similarly, I want controllers which will have routes and methods like below. Say in one a new action is added, the code should enforce it in the other controller.
DemoController
-- GET demo/api/action1
-- GET demo/api/action2
TestController
-- GET test/api/action1
-- GET test/api/action2
How to achieve this?

Well, you've sort of answered your own question, really. If you want to ensure that the same methods are implemented on multiple classes, that is what interfaces are for. You just make each controller implement the same interface and you're good to go.
As for ensuring a similar routing structure, you can use inheritance for that. Define a base abstract controller class. You can either choose to implement your interface here, and "implement" the required methods as abstract. Any derived class will be forced to implement any abstract methods on the base class, so it has the same effect as an interface. That technically means you can forgo the interface, if you want, and just rely on the base class forcing the implementation. Up to you. Then you can apply route attributes to your abstract methods like so:
[Route("[controller]/api")]
public abstract BaseApiController : ControllerBase
{
[HttpGet("action1")]
public abstract IActionResult Action1();
[HttpGet("action2")]
public abstract IActionResult Action2();
}

if you are dealing with different entities that requires similar business logic, you can create generic base controller and inject your common dependencies as well:
[Route("api/[controller]")]
[ApiController]
public class GenericBaseController<T> : ControllerBase where T : class
{
private readonly ILogger _logger;
public GenericBaseController(ILogger<GenericBaseController<T>> logger) {
_logger = logger;
}
[HttpGet("get")]
public IActionResult Get()
{
//...
}
[HttpPost("post")]
public IActionResult Post(T value)
{
//...
}
}
then you can extend the generic controller :
[Route("api/[controller]")]
[ApiController]
public class MyFirstController : MyFirstController<FirstModel>
{
public GenericBaseController(ILogger<MyFirstController> logger) : base(logger)
{
}
}
another one:
[Route("api/[controller]")]
[ApiController]
public class MySecondController : GenericBaseController<SecondModel>
{
public MySecondController(ILogger<MySecondController> logger) : base(logger)
{
}
}
You don't have to re-create the methods for each inherited controller if it is the same logic, or you may extend any of it if you need:
[Route("api/[controller]")]
[ApiController]
public class MyThirdController : GenericBaseController<ThirdModel>
{
public MyThirdController(ILogger<MyThirdController> logger) : base(logger)
{
}
[HttpPost("post")]
public IActionResult Post(ThirdModel value)
{
// do some logic...
return base.Post(value);
}
}

Related

Inject .NET Core object as singleton instance-per-type?

Is it possible using .NET Core dependency injection to have distinct types resolve their own singleton? For example, a transient type resolves in it's constructor a distinct singleton. Even a singleton type in their constructor would resolve to it's own distinct singleton. It is similar to an injected static member on the class type.
HttpClientFactory kind of does this with HttpClient. The HttpClient is disposable but the underlying message handler is a lifetime controlled object for the owner. How could I replicate that?
Ideally the solution wouldn't involve me knowing all types being injected into a constructor -- for example HttpClientFactory does not have that requirement.
Thanks!
If anybody else is interested in the future, I solved this by exploiting generics. For example:
public interface IStaticMember<TOwner, TValue>
where TOwner : class
where TValue : class
{
public TValue Value { get; }
}
Implementation:
public class StaticMember<TOwner, TValue> : IStaticMember<TOwner, TValue>
where TOwner : class
where TValue : class
{
public StaticMember(TValue value)
{
Value = value;
}
public TValue Value { get; private set; }
}
Registration methods...
public static IServiceCollection AddStaticMember<TOwner, TValue>(
this IServiceCollection #this)
where TOwner : class
where TValue : class
{
return #this.AddSingleton<IStaticMember<TOwner, TValue>, StaticMember<TOwner, TValue>>();
}
public static IServiceCollection AddStaticMember<TOwner, TValue>(
this IServiceCollection #this,
Func<IServiceProvider, TValue> valueFactory)
where TOwner : class
where TValue : class
{
return #this.AddSingleton<IStaticMember<TOwner, TValue>>(serviceProvider =>
{
return new StaticMember<TOwner, TValue>(valueFactory(serviceProvider));
});
}
Classes which use it...
public class OwningClass1 : IOwningClass1
{
public OwningClass1(IStaticMember<IOwningClass1, IMyStatic> myStatic) { ... }
}
public class OwningClass2 : IOwningClass2
{
public OwningClass2(IStaticMember<IOwningClass2, IMyStatic> myStatic) { ... }
}
And injecting a static onto a transient (two ways)...
services.AddTransient<IOwningClass1, OwningClass1>();
services.AddTransient<IOwningClass2, OwningClass2>();
services.AddTransient<IMyStatic, MyStatic>();
services.AddStaticMember<IOwningClass1, IMyStatic>();
services.AddStaticMember<IOwningClass2, IMyStatic>();
// or
services.AddTransient<IOwningClass1, OwningClass1>();
services.AddTransient<IOwningClass2, OwningClass2>();
services.AddStaticMember<IOwningClass1, IMyStatic>(serviceCollection => new MyStatic());
services.AddStaticMember<IOwningClass2, IMyStatic>(serviceCollection => new MyStatic());
In both cases, all instances of OwningClass1 get the same instance, and all instances of OwningClass2 get another distinct instance.
Please let me know if there is a better way.

How to show endpoint documentation when my method inherits a base controller

I have multiple classes (more than 100) which inherit from my base class BaseController. All my classes are their logics and models but format's response (200, 404, 500, ...) are always the same.
But when I inherit from my base class, in my swagger documentation I see my endpoints but the details of the response are not there. How can I do this?
public class BaseController : Controller
{
public BaseController() {}
[Produces("application/json")]
[SwaggerResponse(StatusCodes.Status200OK)]
[SwaggerResponse(StatusCodes.Status404NotFound)]
protected async Task<IActionResult> Get(int id)
{
...
}
}
public class MyController : BaseController
{
[HttpGet("{id}")]
public async Task<IActionResult> Get(int id)
{
return await base.Get(id).ConfigureAwait(false);
}
}
As #Helder Sepulveda Said, this goes beyond swashbuckle.
I Think you can use IActionModelConvention to simulate inherit the action attributes.
Use Action.Filters like this
public class ActionMethodConvention : IActionModelConvention
{
public void Apply(ActionModel action)
{
var actonBaseResponses = new List<SwaggerResponseAttribute>();//some code to get baseAction reflections
foreach (var attr in actonBaseResponses)
{
action.Filters.Add(new Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(actonBaseResponses.StatusCode));
}
}

How to add base controller in asp.net mvc 6

I search about base controller in asp.net mvc 6 however there is no any source (as far as i check).So how can i add base controller in asp.net mvc and use services on constuctor method or create new methods in base controller or any idea in order to use anything like base controller?
Any help will be appreciated.
Thanks.
You can add base controller in the following way:
public class BaseController : Controller
{
public IService Service { get; }
public BaseController(IService service)
{
Service = service;
}
}
Then, you can create your own controller and inherit BaseController instead of Controller class.
public class NewController : BaseController
{
public NewController(IService service) : base(service)
{
}
public IActionResult NewAction()
{
var result = Service.ServiceMethod();
}
}
With Microsoft.Extensions.DependencyInjection name space gives us access to the following extension method HttpContext.RequestServices.GetService
Here’s the source code of our BaseController class
public abstract class BaseController<T> : Controller where T : BaseController<T>
{
private IService service;
protected IService _service => telemetryInitializer ?? (telemetryInitializer = HttpContext.RequestServices.GetService<West.TelemetryService.ITelemetryHelper>());
}
The OrderController class extends this abstract BaseController
public class OrderController : BaseController<OrderController>
{
private readonly IOrderManager _orderManager;
public OrderController(IOrderManager orderManager)
{
_orderManager = orderManager;
}
[HttpGet]
public string Get()
{
Logger.LogInformation("Hello World!");
return "Inside the Get method of OrderController";
}
}

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")));
...
}

ASP.NET MVC, Ninject, single instance per request for multiple constructors

Im trying to implement an unit of work pattern by passing an unit of work instance into my repositories.
Relevant code from Global.asax.
public class SiteModule : NinjectModule
{
public override void Load() {
Bind<IUnitOfWork>().To<SqlUnitOfWork>()
.InRequestScope()
.WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["Entities"].ConnectionString);
Bind<IProductRepository>().To<ProductRepository>();
Bind<ICategoryRepository>().To<CategoryRepository>();
}
}
Repository constructors:
public class ProductRepository {
IUnitOfWork unitOfWork;
public ProductRepository(IUnitOfWork unitOfWork) {
this.unitOfWork = unitOfWork;
}
}
public class CategoryRepository {
IUnitOfWork unitOfWork;
public CategoryRepository(IUnitOfWork unitOfWork) {
this.unitOfWork = unitOfWork;
}
}
What i want is that a maximum of 1 instance of SqlUnitOfWork is created per request and is passed into my repositories (via their respective constructors).
Is the InRequestScope() method on the IUnitOfWork binding enough? If not how can i achieve this?
The code you have will work fine. Only one instance of IUnitOfWork will be given to any class that requests it (via constructor/property injection or calls to the kernel's .Get<> etc.)

Resources