Good time
I have three layers of UI, BLL, DAL.
I added a WEB API layer. I also have a class called PersonController, which I added to the WEB API project. The class is:
public class PersonController : ApiController
{
public IEnumerable<CommonPerson> GetAllPersons()
{
PersonRepository PersonRep = new PersonRepository();
return PersonRep.SelectAll();
}
}
In the GetAllPersons action, the PersonRepository class is called and goes to DAL from DbContext on the database queries.
The problem with this is that it can not read in the DAL, which can be read connection string, and make a mistake.
How can I connect the web api with the dal layer?
A good practice is:
DbContext => Repository => Unit of Work => BLL => ApiController
Here is a good resource:
http://jasonwatmore.com/post/2015/01/28/unit-of-work-repository-pattern-in-mvc5-and-web-api-2-with-fluent-nhibernate-and-ninject
Related
I'm injecting a business layer into a self-hosted (InstanceContextMode=per-call) WCF service by leveraging AutoFac's ServiceHost.AddDependencyInjectionBehavior() extension (as described in the Autofac documentation)
My business layer uses components that cannot be re-created each time a new request comes in (let's say it needs a persistent database connection).
As such, when building the container I'd like to register the BL service as a Single instance, i.e.:
builder.RegisterType<BusinessLayer>()
.SingleInstance();
The business-layer injection into the WCF service is working fine; my issue is that:
Dispose() is not called on ANY services created in the container: not just the Business layer itself, but the 'persistent' services too.
I'd expect this to happen for the BL service itself. From the Autofac docs again:
If you have singleton components (registered as SingleInstance()) they will live for the life of the container. Since container lifetimes are usually the application lifetime, it means the component
won’t be disposed until the end of the application.
, but why are none of my 'child' (Autofac-registered) services (i.e the 'IPersistentService' below) disposed when the lifetime scope is -- given that I'm not explicitly making them 'SingleInstance'?
Note:: this is still the case if I manually dispose the business layer service within the lifetime scope after I close the ServiceHost
E.g. (IDisposable implementations omitted for brevity):
[ServiceContract]
public interface IMyService
{
void DoStuff();
}
public class MyService : IMyService
{
IBusinessLayer _bl;
public MyService(IBusinessLayer bl)
{
_bl = bl;
}
public void DoStuff()
{
_bl.BLDoStuff();
}
}
public interface IBusinessLayer
{
void BLDoStuff();
}
public class BusinessLayer : IBusinessLayer
{
IPersistentService _service;
public BusinessLayer(IPersistentService service)
{
_service = service;
}
public void BLDoStuff()
{
// Do something that requires a 'cached' / persistent component
_service.DoSomethingWithPersistentConnection();
}
}
public interface IPersistentService : IDisposable
{
void DoSomethingWithPersistentConnection();
}
With Autofac registrations looking something like:
builder.RegisterType<BusinessLayer>()
.SingleInstance();
builder.RegisterType<MyPersistentService>()
.As<IPersistentService>()
.OnActivated(e => e.Instance.Start());
As Steven mentioned, what you experience here is a Captive Dependency problem. In other words, a singleton (BusinessLayer, registered with .SingleInstance()) keeps a lifetime-scoped or transient dependency (MyPersistentService, registered by default as transient).
Put it this way, dependencies of singleton services will always be singletons themselves, no matter how they were registered in the container. The diagram in Mark Seeman's article that Steven linked to gives a good view of this.
I think you can achieve what you expect, but your registrations are wrong.
My business layer uses components that cannot be re-created each time a new request comes in (let's say it needs a persistent database connection).
As such, when building the container I'd like to register the BL service as a Single instance
This is where the problem is. It's the dependency of the business service that has to be registered as a singleton, not the business service itself. This means you could have Autofac create a different instance of BusinessLayer for each WCF call, but the MyPersistentService instance injected into would always be the same. Does this make sense? Your registrations would then look like:
builder
.RegisterType<BusinessLayer>()
.As<IBusinessLayer>()
.InstancePerLifetimeScope(); // a new instance per WCF call
builder
.RegisterType<MyPersistentService>()
.As<IPersistentService>()
.OnActivated(e => e.Instance.Start())
.SingleInstance(); // one same instance for the lifetime of the application
The one instance of MyPersistenService would then be disposed of only after disposing the root container (that you created by calling builder.Build()) after you close the Service Host.
I am using System.Web.Mvc.Controller for the UI and System.Web.Http.ApiController for the API in prototyping a web interface for large ERP application. I have figured out a way to make the UI somewhat extensible with the question Deploying un-compiled ASP.NET MVC Razor application. Now I am wondering, due to the strict nature of ApiController if there is some other class I should be considering for providing an open-ended interface for defining custom API transactions. Or is there some way to use ApiController in a more open-ended way where parameter count and type may be varied... perhaps by accepting an object parameter?
For Web API, you could try implementing a custom action selector using IHttpActionSelector interface:
public class CustomActionSelector : IHttpActionSelector
{
public override HttpActionDescriptor SelectAction(HttpControllerContext context)
{
var method = GetMethod(context);
return new ReflectedHttpActionDescriptor(GetController(method), method);
}
private MethodInfo GetMethod(HttpControllerContext context)
{
// Locate the target method using the extensibility framework of your choice
// (for example, MEF, pure reflection, etc.)
}
private HttpControllerDescriptor GetController(MethodInfo method)
{
return new HttpControllerDescriptor()
{
ControllerName = method.DeclaringType.Name,
ControllerType = method.DeclaringType
};
}
}
To register your new action selector place the following in your global.asax file under Application_Start:
var config = GlobalConfiguration.Configuration;
config.Services.Replace(typeof(IHttpActionSelector), new CustomActionSelector());
Hope this helps.
To make an ASP.NET web application extensible is very straightforward because ASP.NET searches the bin directory for controller classes in all assemblies there. So if the party providing customizations can simply compile their code into a DLL and drop it into the bin directory, your web application will pick up all their controllers as well as the controllers from the standard delivery. As an example, I created the following class in a standalone DLL that referenced System.Web.Http and System.Web.Mvc:
Public Class CustomTestController
Inherits ApiController
Public Function GetValues() As IEnumerable(Of String)
Return New String() {"value1", "value2"}
End Function
End Class
I simply compiled it and copied it to the bin directory of the location where my web application was deployed, and then I could access http://localhost/MyApplication/api/CustomTest/ and get back value1 and value2 in the expected response.
This one is driving me mad. I've read the Ninject docs, I've read the docs for the Ninject MVC extension, I've lost count of how many related SO questions I've read, and I have no idea where the problem is with my code.
I'm building a webapp in ASP.NET MVC 4, and I'm using Ninject to bind repository interfaces. The docs say that if you add Ninject using NuGet (which I did), then it wires everything up for you so you don't need to have your application inherit from NinjectHttpApplication (so I haven't) and you just need to add your bindings in NinjectWebCommon.RegisterServices(), (which I have). I have an IRepository<T>, and a Repository<T>. The user repository has a few extra methods for login and registration, so there's a separate UserRepository which implements IRepository<User>. My bindings therefore look like this:
kernel.Bind(typeof(IRepository<>)).To(typeof(BaseRepository<>)).InRequestScope();
kernel.Bind(typeof(IRepository<User>)).To(typeof(UserRepository)).InRequestScope();
The docs, and a couple of SO questions, also mention that if you added Ninject though NuGet (which I did) then it sorts out the controller factory for you and you don't need to implement your own Ninject-y controller factory (so I haven't). My controllers inherit from a BaseController, which has a constructor that accepts a set of IRepository-compatible repositories. Now, from what I've read, when I try to use a controller, Ninject should recognise the IRepositoriy parameters and provide them. It doesn't. Even if I put the [Inject] attribute on the constructor, it still gets ignored - the parameterless constructor gets called instead. If I remove the parameterless constructor, I get a compile error complaining that there isn't one.
What have I missed? How do I get Ninject to provide my repositories?
Weird, I am unable to reproduce the problem you are describing.
Steps:
Create a new ASP.NET MVC 4 application using the Internet template
Install the Ninject.MVC3 NuGet
Define some classes:
public interface IRepository<T>
{
}
public abstract class BaseRepository<T> : IRepository<T>
{
}
public class User
{
}
public class UserRepository : BaseRepository<User>
{
}
public abstract class BaseController<T>: Controller
{
protected BaseController(IRepository<T> repository)
{
this.Repository = repository;
}
protected IRepository<T> Repository { get; private set; }
}
public class HomeController : BaseController<User>
{
public HomeController(IRepository<User> repository): base(repository)
{
}
public ActionResult Index()
{
return Content(this.Repository.GetType().ToString());
}
}
And wire them up in ~/App_Start/NinjectWebCommon.cs:
private static void RegisterServices(IKernel kernel)
{
kernel
.Bind(typeof(IRepository<User>))
.To(typeof(UserRepository))
.InRequestScope();
}
Run the application and the proper instance of the repository gets injected into HomeContorller.
I tried to minimize writing of code for WCF CRUD part of big project with use of generics and castle WCF facility.
I have WCF service contract:
[ServiceContract]
public interface IResourceService : ICRUDService<DTOResource>
{
[OperationContract]
DTOResource Get(long id);
}
and generic interface
public interface ICRUDService<T> where T is IDTO
{
T Get(long id);
}
also generic MVC controller (1 controller for all basic crud for dtos and services)
public class CRUDController<T> : Controller where T is IDTO
{
readonly ICRUDService<T> service;
public CRUDController(ICRUDService<T> service)
{
this.service = service;
}
}
On the client side i register WCF client in Windsor Container
Component
.For<IResourceService , ICRUDService<DTOResource>>()
.AsWcfClient(... standard stuff... )
Everythig is working fine, components and services registered, controller created properly,
service
readonly ICRUDService<T> service;
in controller is of type
Castle.Proxies.IResourceService
But when i try to use service in controller i have error
Method Get is not supported on this proxy, this can happen if the method is
not marked with OperationContractAttribute or if the interface type is not
marked with ServiceContractAttribute.
When in controller i hardcode cast
((IResourceService)service).Get(id);
all is running properly, so i believe this problem is solvable.
I've also tried to use Forward (with same result) :
Component
.For<IActionTypeService>
.Forward<ICRUDService<DTOResource>>().AsWcfClient(...
How to make it work?
In the end i had to use 'Channel Factory' on client side.
I was able to use Windsor WCF Facility on server side to register generic contract :
[ServiceContract]
public interface ICRUDService<I>
{
[OperationContract]
I Get(int id);
}
with generic implementation
public class CRUDService<I, IEntity> : ServiceBase, ICRUDService<I>
{
public I Get(int id)
{
...
}
in standard way (for multiple types)
private void InstallExample<I, IEntity>(IWindsorContainer container)
{
container.Register(
Component
.For<ICRUDService<I>>()
.ImplementedBy(CRUDService<I, IEntity>)
.Named("somename")
.AsWcfService(
new DefaultServiceModel()
.Hosted()
.PublishMetadata(x => x.EnableHttpGet())
.AddEndpoints(WcfEndpoint
.BoundTo(new BasicHttpBinding())
.At("someAddress")
)
)
.LifeStyle.PerWcfOperation();
}
with fileless activation in web.config
<add factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" service="ClientService" relativeAddress="./ClientService.svc" />
On server side it works perfectly. Sadly on client side i didn't found working solution for WCFFacility and i had to use ChannelFactory (which is working perfectly)
ChannelFactory<ICRUDService<I>> factory = new ChannelFactory<ICRUDService<I>>(someBinding, someEndpoint);
For the rest (standard non generic services i'm using WCF Facility without any problems.
I think you need to put the ServiceContract attribute on ICrudService<>, add the OperationContract to the method there and remove the duplicate declaration of Get() from IResourceService.
I am trying to figure how to create tests for my controllers that are consuming a WCF service (via a proxy class)
The proxy class is pretty much identical to the one listed in this post http://blog.weminuche.net/2008/08/test-post.html
Base Controller
public abstract class ServiceProxyController<TService> : Controller
where TService : class
{
private readonly ServiceProxy<TService> _proxyHelper;
protected ServiceProxyController(string endpoint)
{
_proxyHelper = new ServiceProxy<TService>(endpoint);
}
private Stuff GetStuff(int num)
{
Call((service) => {
service.DoSomeStuff(num)
});
................
}
...........
}
Controller Implementation
public class MyController : ServiceProxyController<IService>
{
public MyController() : base("ServiceBindingName")
{
}
}
I want to be able to inject a proxy helper(???) into my controller so as I can mock it and therefor test the controller
How about injecting the proxy helper to the constructor (notice the introduction of an abstraction):
private readonly IServiceProxy<TService> _proxyHelper;
protected ServiceProxyController(IServiceProxy<TService> proxyHelper)
{
_proxyHelper = proxyHelper;
}
and the controller:
public MyController(IServiceProxy<TService> proxyHelper)
: base(proxyHelper)
{
}
This way in your unit test when instantiating the controller you could inject a mocked instance of the IServiceProxy<TService> interface.
You will then need to configure your DI framework to insert the proper implementation into the controller constructor which will wrap the actual ChannelFactory.
I just asked a similar question. I am injecting the service using structure map. I am dynamically creating a proxy using channel factory.
Look at this example for using Channel factory.
creating WCF ChannelFactory<T>
My question for your reference.
Rhinomocks - Mocking delegates
Note- Actually it was Darin who posted the ServiceInvoker