Call web api in web form by referencing API dll - asp.net-web-api

is it Ok if we call wep api service inside web form using api dll. we will be hosting both api and application on same server and requiring internal calling.

It's not very clear what you are after.
First of all if you write an API of some kind then you have to call it to interact with it. There's no middle ground here. If you don't want to call anything then you don't need an API. The purpose of an API is to provide a way to interact with some data storage, so behind your controllers you'd have a layer which talks to a database for example, or even another API.
If you don't want to make any calls then why bother with an API at all? Write a class library, one or several, doing whatever you need them to do and interact with your database this way.
I worked in a project before where I had a somewhat similar situation and ended up writing class libraries which were then shared by a UI project and a WebApi project, so you could work with them either way. This worked quite well actually. If you are looking for something similar then that's what I would go with. Keep the stuff of interest separate so you can expose with an API call or a direct dll reference.

So assuming that your controller methods look something like this:
public interface IService
{
Task<Value> GetValueAsync(int id);
}
public class Service : IService
{
public Task<Value> GetValueAsync(int id)
{
//...
// Code to return a value
//...
}
}
public class ValueController : ApiController
{
private IService _service;
public ValueController(IService service)
{
_service = service
}
public Task<IHttpActionResult> GetValueAsync(int id)
{
return Ok(await _service.GetValueAsync(id));
}
}
Then it is perfectly okay to call the method in the Service class. I would not call the method in the controller as that will cause more problems than you probably want to deal with.

Related

Spring kotlin - How to inject internal class to public class

I have some problem but also I don't know if my approach is right so I decided to ask you about it. I try to create public facade (for REST controllers or another modules) in application layer which should communicate with domain layer. The problem is that it seems to me that everything in domain should be internal and when I want to inject some service from domain to facade then intellij returns me error: 'public' function exposes its 'internal' parameter type SomeService. What is the best approach for this case? Should I make interface SomeService as public? But then any other modules also could inject it what is probably wrong :/
example code:
applicaion layer:
class MyFacade(
private val myInternalService: InternalService
){
fun save(...){
return myInternalService.save(...)
}
}
domain layer:
internal interface InternalService {
fun save(...)
}
and rest implementation of domain...

WebApi controller accessing its StatelessService instance

I am hosting WebApi controller inside a stateless service with one instance. The service instance (I mean the instance of the WebApiService class created by the SF runtime) maintains some transient state as member fields, exposing the state through internal (thread-safe) methods. The WebApi controller needs to call the methods to access that state.
WebApiService.cs:
-----------------
internal sealed class WebApiService : StatelessService
{
private int _state;
internal int GetState() { return this._state; }
ServiceController.cs:
---------------------
public class ServiceController : ApiController
{
public async Task<IHttpActionResult> GetStateAsync()
{
// Here I'd like to grab somehow the WebApiService instance
// and call its GetState internal method.
My questions are:
How can the controller get a reference to the WebApiService instance?
Is it safe to store the WebApiService instance in a static field (perhaps set in the WebAspiService constructor)?
Inject the service instance as a dependency to your controllers through a DI container.
Here's an example with Web API hosted on Katana using Unity. It's a stateful service but it works exactly the same way for a stateless service: https://github.com/Azure-Samples/service-fabric-dotnet-getting-started/tree/master/Services/WordCount/WordCount.Service
Here's an example using Asp.Net Core and its built-in dependency injection container (also stateful, but same thing applies): https://github.com/vturecek/service-fabric-xray/tree/master/src/xray.Data
I think you could use a DI container for that. I can recommend simpleinjector (but there are many that can do the same), simpleinjector has got object lifetime management also per request and a web api package. You could put your state instance in a container as a singleton and inject it in your controllers, that would be a thread safe way, better stay away from static fields in a multithreaded web environment.
You have to resolve the stateless service in your controller before you can call the methods of the stateless service:
public async Task<IHttpActionResult> GetStateAsync()
{
var proxyLocation = new ServiceUriBuilder("WebApiService");
var svc = ServiceProxy.Create<IWebApiService>(proxyLocation.ToUri());
return svc.GetState();
}
You need to create an interface IWebApiService that contains the GetState method. WebApiService needs to implement it. Basically you need to abstract WebApiService with the IWebApiService interface.

WebAPI: Accessing Child Container as a Service Locator

In normal ASP.MVC projects we configure the dependency resolver with Unity and the Unity.Mvc3 package from http://unitymvc3.codeplex.com/
We have this test service registered with a HierarchicalLifetimeManager
container.RegisterType<ITestService, TestService>(new HierarchicalLifetimeManager());
And we hook up the container with Mvc in Global.asax.cs:
System.Web.Mvc.DependencyResolver.SetResolver(new Unity.Mvc3.UnityDependencyResolver(container));
And we run this test controller:
public class TestController : Controller
{
private readonly ITestService _service;
public TestController(ITestService service)
{
this._service = service;
}
public ActionResult Test()
{
var locatedService = System.Web.Mvc.DependencyResolver.Current.GetService<ITestService>();
if (_service == locatedService)
return View("Success - Same Service");//This is always the result in an MVC controller
else
throw new Exception("Failure - Different Service Located");//This is never the result in an MVC controller
}
}
However, on this project we are adding a number of WebAPI controllers.
We have this configuration in global.asax.cs (using http://unitywebapi.codeplex.com/ for now. But I am open to suggestions):
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
We have created an ApiTestController similar to TestController inheriting from ApiController rather than from Controller.
However, the ApiTestController fails its test. I understand that the System.Web.Mvc.DependencyResolver class and the System.Web.Mvc.DependencyResolver.Current property are specific to Mvc. But does WebAPI have an equivalent?
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver.GetService does not work because the System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver instance is the parent container that I configured. It is not the child controller that was used to inject the ITestService into the constructor.
This user seems to have a similar problem: http://unitywebapi.codeplex.com/discussions/359413
But I feel that this probably has more to do with ASP.NET's WebAPI than it has to do with Unity.
Thanks
After looking over the source of http://unitymvc3.codeplex.com/ and http://unitywebapi.codeplex.com/ I created this class:
public class MyUnityDependencyResolver : Unity.Mvc3.UnityDependencyResolver, System.Web.Http.Dependencies.IDependencyResolver
{
public MyUnityDependencyResolver(IUnityContainer container)
: base(container)
{
}
public System.Web.Http.Dependencies.IDependencyScope BeginScope()
{
return this;
}
public void Dispose()
{
Unity.Mvc3.UnityDependencyResolver.DisposeOfChildContainer();
}
}
Configuration in gobal.asax.cs:
var myResolver = new MyUnityDependencyResolver(container);
System.Web.Mvc.DependencyResolver.SetResolver(myResolver);
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = myResolver;
Unity.Mvc3.UnityDependencyResolver uses HttpContext.Current.Items to manage child containers. MyUnityDependencyResolver may not be the most "correct" implementation of System.Web.Http.Dependencies.IDependencyResolver, but it seems to work so far.
I will mark this as the answer in a couple days if no one else has any better answers.
Unfortunately, when you call the GlobalConfiguration.Configuration.DependencyResolver.GetService, it completely ignores any scope and resolves using the outer non-child container which is around for the lifetime of the application. This is an issue with Web Api and makes it impossible to use constructor injection for per-request dependencies outside of controllers. Confusingly this is completely different behaviour from MVC as you say.
What you can do is use the GetDependencyScope() extension method off HttpRequestMessage. Anything you resolve using this will be in per request scope when using HierarchicalLifetimeManager in conjunction with Unity.WebApi. The request is available from action filters and handlers so may be a viable workaround.
Obviously this is pure service location rather than dependency injection which is far from ideal but I have not found another way to access per-request dependencies outside of controllers.
See this post for more info.
The DependencyResolver is not the right seam for dependency injection in ASP.NET WebAPI.
Mark Seemann has two really good posts on DI with WebAPI.
Dependency Injection and Lifetime Management with ASP.NET Web API
Dependency Injection in ASP.NET Web API with Castle Windsor
If you want to do it right you should have a look at them.

conditional disposing of objects using DI framework (Ninject)

I have the following code
public class MyService : IMyService
{
private readonoly IUnitOfWork _unitOfWork;
public MyService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
}
//This code is used by web client
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IMyService>().To<MyService>();
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
}
I have a web and windows service client both use the "MyService" class. I want to dispose the "unit of work" at the end of HTTP request if the client is web, where as if the client is a windows service, I want to dispose the unit of work after every database call. how to achieve that? can I add an extra flag to the MyService constructor, to identify the client, but then how to modify the above code to pass a hardcoded value to that parameter when mapping the concrete types to the interfaces?
You will probably have some sort of MyServiceRunner in yourr Windows service that calls your MyService. This class is Windows service specific and this would be the place to explicitly control the lifetime of the IUnitOfWork. Or you can write a decorator for MyService that controls the unit of work.
A few things to note. Although you can reuse the IUnitOfWork on a per-web-request basis, DO NOT Commit the unit of work at the end of the web request, but explicitly do this after a service (succesfully) executed. Since the scope of your IUnitOfWork is very different in the Windows Service, you probably need some explicit code or explicit registration to handle this. However, make sure that your MyService is oblivious to this: It shouldn't need to care.
If you have many services that you want to call in the Windows Service, you might want to think about applying the command/handler pattern for handling business logic. You can read more about it here.

Setting Session in MVC3 when the class not inherited from controller or helper

I would like to write and read data to Session even if my class not inherited from controller or helper. Something like this:
public class User
{
public void CreateSession()
{
Session["key"]=data;
}
public void ReadSession()
{
data=(string)Session["key"];
}
}
Important thing - I need to get instance of User class in some actions
and views. Am I be able to inherit User class from controller or
helper. Because I've already try that, but I got some errors.
How can I achive this?
Thanks in advance.
HttpContext.Session will work, it's a static available anywhere to an assembly that references System.Web.
If your code is in your main website assembly, this should work well. If it's not, you'll have to create a dependency on System.Web which you may or may not want to do.
You should do these kind of things in your controller.
You can access HttpContext directly, but that's not "the ASP.NET MVC way", and you loose some of the advantages of using MVC in the first place. Like making testing harder, and directly coupling your application to HttpContext...
Also, if it's a new session, or Session["key"] is not set for some reason, data=(string)Session["key"]; would throw a null reference exception.

Resources