I use S#arp Architecture which uses Windsor Castle for IoC. I got a new controller now that, unlike all other controllers in the project, need a different implementation of the same interfaces. I.e. all controllers use ProductsRepository: IProductsRepository as implementation, but the new one has to use SpecificProductsRepository.
How do I configure it to recognize and manage this automatically? Either in pure Windsor way, or with ASP.NET MVC help (e.g. in my custom controllers factory).
OK looks like I need subcontainers. Still searching.
An easier and much simpler way would be to use Windsor's service overrides.
E.g. register your repos like so:
container.Register(Component.For<IProductsRepository>
.ImplementedBy<ProductsRepository>()
.Named("defaultProductsRepository"),
Component.For<IProductsRepository>
.ImplementedBy<SpecificProductsRepository>()
.Named("specificProductsRepository"));
which will ensure that the default implementation is ProductsRepository. Now, for your specific controller, add a service override like so:
container.Register(Component.For<NewController>()
.ServiceOverrides(ServiceOverride
.ForKey("productsRepository")
.Eq("specificProductsRepository"));
You can read the docs here.
Edit: If you want to register your repositories with AllTypes, you can adjust the registration key e.g. like so:
container.Register(AllTypes.[how you used to].Configure(c => c.Named(GetKey(c)));
where GetKey e.g. could be something like:
public string GetKey(ComponentRegistration registration)
{
return registration.Implementation.Name;
}
OK, these days I tend to answer my own questions... so here it is for those who need it.
// create subcontainer with specific implementation
var mycontainer = new WindsorContainer();
mycontainer.Register(AllTypes.Pick()
.FromAssemblyNamed("My.Data")
.WithService.FirstInterface()
.Where(x => x.Namespace == "My.Data.Custom")
.Configure(x => x.LifeStyle.Is(LifestyleType.PerWebRequest)));
container.AddChildContainer(mycontainer);
ControllerBuilder.Current.SetControllerFactory(new ExtendedControllerFactory(
new Dictionary<string, IWindsorContainer> { {"", container}, {"Lm", mycontainer} }));
The controller factory chooses appropriate container based on name. The biggest challenge there is to call appropriate container's Release(controller) at the end of request, i.e. remember which container was used to instantiate controller. But this can be solved in several ways I suppose - remember in thread-specific (in HttpContext), remember in BaseController property, remember in internal dictionary, etc.
Related
I'm working on ASP.NET MVC application & have a quick design question for you.
So I need to implement a common functionality for all my controllers (well, most of them).
I don't want to repeat the same logic in all the controllers.
What'd be the ideal approach in the best interest of MVC?
I found people saying create base controller and inherit it in your controllers. But when I visualize a controller, I can see it'd contain only action methods that return some content/views - Correct me if I'm wrong.
OneController
{
ActionMethod A1
{
//Code to return list of objects for the given integer value. So it calls database stored procedure.
}
}
...multiple such controllers are there.
I'd still like to have A1 exists in the OneController, just put its logic somewhere common place.
Also some people suggest to create just plain Helper class to place the common method.
Could you please suggest me what approach will be better (Or any other appropriate approach)? Thanks.
I agree with you that, most of the times, it only makes sense to inherit from base controllers when we're talking about Actions or methods that are really related. But of course, you can just use base controllers for everything. Your choice.
Other than that, you have 2 options. For classes that have little to no chance of being polymorphic (change behavior depending on the implementation), you are fine to create static classes and just use them inside your controllers. An example would be a class that does math calculations, these are not that polymorphic by nature.
For all the other cases, I'd strongly suggest that you use dependency injection. One of the reasons being that unit testing will become way easier. Here's a guide on how to do it for MVC 4 onwards using the built in engine: https://www.asp.net/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-dependency-injection. If you don't want to use it and use Ninject or Simple Injector, you can implement your own ControllerActivator and use Ninject, for instance, to get an instance of your controller.
When using dependency injector, normally your controller would get the dependencies in the constructor, like this:
public class StoreController : Controller
{
private IStoreService service;
public StoreController(IStoreService service)
{
// service in an injected dependency
this.service = service;
}
}
For more information, Google ASP.NET dependency injection.
I am developing an MVC app to serve multiple domains - each is a branch of a larger company.
A LocalBranch class stores details such as phone, address, email, location coordinates etc.
I want to create a single instance of this class per http request and have it available throughout the application - from within controllers, views, some helper classes and other code.
Is there a recommended way of doing this?
Right now I have it as a property on a BaseController and use ViewBagto pass it to views. But I would prefer it strongly typed in Views if possible.
I don't want to put it in an application variable, because we need to serve different values to different domains.
I would rather avoid a session variable if possible because we might scale up to use multiple servers in the future, and I've heard this doesn't play well with sessions.
Please feel free to update tags / title if you think there is a clearer way of expressing what I'm after. Thank you.
The best way to maintain your state in a web application per request is simply use the HttpContext class.
You need to store your state(LocalBranch) as an Item in the HttpContext:
HttpContext.Current.Items.Add("LocalBranch", GetLocalBranch());
You can fetch the Item all across your application like this:
LocalBranch branch = HttpContext.Current.Items["LocalBranch"] as LocalBranch;
The Items property is simply a key value Dictionary. The value is an object. You will have to check for nulls and this is really similar to the Session object you know. The main difference is the scope. The HttpContext is a dot net object that has a lifetime of an http request.
Now using the HttpContext the way I've shown you is the simplest way to do it.
You can go two steps forward and use a framework called Unity and add a lifetime to your objects.
Unity does much more and the lifetime management is just one gem.
You can create a custom HttpContext lifetime that generates objects per request. Something like this.
And them all you need to do is:
1.Register you LocalBranch class with the HttpContext lifetime.
2.Add a static Current property which will use the Unity container and resolve the correct instance of LocalBranch.
3.Use it something like this: LocalBranch.Current
BTW, you can use Unity's dependency injection for injecting objects into controllers and other modules. That's a better practice then just using the static Current property.
You kind of have two questions here. The first is "How do I create a single instance of this class per HttpRequest?" The second is "How do I make this available to strongly typed views?"
The first has pretty much been answered by #amir-popovich to use dependency injection. However, FWIW I would probably use Ninject instead of Unity (just preference, really) and I would probably implement it differently. I would not use HttpContext, and simply build a service (which is instanciated using Ninject's OnePerHttpRequest Module, passing the domain as an argument to get the proper values).
Then, in order to add these LocalBranch values to your strongly typed View Model, you can first create a base view model which holds this type:
public class BaseViewModel
{
public LocalBranch Branch {get;set;}
}
Then, make all of your current view models inherit this base type
public MyViewModel : BaseViewModel
{
public string SomeValue {get;set;}
}
Then in your controller, it is easy enough to add these values from the service you created from the first step
public ActionResult SomeAction()
{
var vm = new MyViewModel();
vm.Branch = LocalBranchService.GetLocalBranchValues(); //Local Branch Service has been injected with Ninject
//do other stuff
return View(vm);
}
However, that gets pretty tedious to add that to each controller action, so you can instead create a Result Filter to add it for you:
public class LocalBranchResultFilter : FilterAttribute, IResultFilter
{
public void OnResultExecuting(ResultExecutingContext filterContext)
{
//This method gets invoked before the ActionResult is executed.
filterContext.Controller.ViewData.Model.Branch = LocalBranchService.GetLocalBranchValues(); //Local Branch Service has been injected with Ninject
}
}
Now, you can just decorate your Controller and/or Actions with the filter (you could even set it in the Global Filters if you want).
You can embed the child actions into your layout or a view. You can even cache its output so you don't keep re-querying the database.
controller
[ChildActionOnly]
[OutputCache(Duration=500, VaryByParam="*")]
public ActionResult Info()
{
var localBranch = db.GetLocalBranch();
return PartialView("_Info", localBranch);
}
_Info view
This bit will get inserted into your other views
#model LocalBranch
<span>#Model.address</span>
<span>#Model.phone</span>
Use in _Layout or other view
<p>lorem ipsum...</p>
#Html.Action("Info")
I'm using structuremap and Asp .Net MVC in a project. Currently I'm registering my dependency resolutions in the MVC layer for everything below it (service, data, etc.). However, I was wondering how I could do this by only registering what's directly below the MVC layer, namely, the Service layer. Basically my controllers have services injected into them and that's all I want my UI layer to know about. Within the service classes I have repositories injected and want those registered with structuremap in there... and so on. In other words, I want each layer to only be dependent (as much as possible) to the layer directly below it.
Thanks!
A good approach is to use structuremap conventions combined with structuremap registries. That will take care of most of your registration issues. Structuremap can scan your bin and map dependencies that it finds in all dll's in your bin.
Look into the Scan method combined with a StructureMap Registry class:
Scan(x =>
{
x.AssembliesFromApplicationBaseDirectory(y =>
y.FullName.StartsWith("JustLookAtTheseDlls"));
// Use default conventions
x.WithDefaultConventions().OnAddedPluginTypes(y =>
y.HybridHttpOrThreadLocalScoped());
//Are there any registries? If so, register them
x.LookForRegistries();
}
A registry looks something like this, and you can just drop one into each of your projects to register the items in each:
public class IocRegistry :
StructureMap.Configuration.DSL.Registry
{
public IocRegistry()
{
For<IDocumentStore>().Singleton()
.Use<RavenStore>();
}
}
You root application should have the registry that contains the scan statement above. Then initialize structuremap like so:
ObjectFactory.Configure(x => x.AddRegistry(
new MyTopLevelRegistry()));
Where MyTopLevelRegistry looks like this:
public class MyTopLevelRegistry: Registry
{
public MyTopLevelRegistry()
{
Scan(x =>
{
x.AssembliesFromApplicationBaseDirectory(
y => y.FullName
.StartsWith("InsertYourNamespacePrefix"));
x.WithDefaultConventions().OnAddedPluginTypes(
y => y.HybridHttpOrThreadLocalScoped());
x.LookForRegistries();
});
}
}
Keep in mind if you set it to "WithDefaultConventions" it will automatically map IMyClass to MyClass so you don't even have to specify that stuff in the registries. You just have to register items that don't follow that convention.
Hope this helps!
I recommend the usage of a composition root in a own library.
In the project i am working on we put the StructureMap registry in a library named xx.yy.IoC and we call the configuration code from Global.asax.
The MVC layer has only a link to the IoC library. The IoC Library has the dependencies to the other layers (Domain, Data, etc.)
As a tip: This article has changed our views about layering. jeffrey palermo onion architecture
I'm not sure I understand what you are asking.
You have to register all the objects that will be resolved. Then in your controller you just expect ISomeService passed to constructor. Controller doesn't know that ISomeService has injected IRepositories for example.
I'm practicing DDD with ASP.NET MVC and come to a situation where my controllers have many dependencies on different services and repositories, and testing becomes very tedious.
In general, I have a service or repository for each aggregate root. Consider a page which will list a customer, along with it's orders and a dropdown of different packages and sellers. All of those types are aggregate roots. For this to work, I need a CustomerService, OrderService, PackageRepository and a UserRepository. Like this:
public class OrderController {
public OrderController(Customerservice customerService,
OrderService orderService, Repository<Package> packageRepository,
Repository<User> userRepository)
{
_customerService = customerService
..
}
}
Imagine the number of dependencies and constructor parameters required to render a more complex view.
Maybe I'm approaching my service layer wrong; I could have a CustomerService which takes care of all this, but my service constructor will then explode. I think I'm violating SRP too much.
I think I'm violating SRP too much.
Bingo.
I find that using a command processing layer makes my applications architecture cleaner and more consistent.
Basically, each service method becomes a command handler class (and the method parameters become a command class), and every query is also its own class.
This won't actually reduce your dependencies - your query will likely still require those same couple of services and repositories to provide the correct data; however, when using an IoC framework like Ninject or Spring it won't matter because they will inject what is needed up the whole chain - and testing should be much easier as a dependency on a specific query is easier to fill and test than a dependency on a service class with many marginally related methods.
Also, now the relationship between the Controller and its dependencies is clear, logic has been removed from the Controller, and the query and command classes are more focused on their individual responsibilities.
Yes, this does cause a bit of an explosion of classes and files. Employing proper Object Oriented Programming will tend to do that. But, frankly, what's easier to find/organize/manage - a function in a file of dozens of other semi-related functions or a single file in a directory of dozens of semi-related files. I think that latter hands down.
Code Better had a blog post recently that nearly matches my preferred way of organizing controllers and commands in an MVC app.
Well you can solve this issue easily by using the RenderAction. Just create separate controllers or introduce child actions in those controllers. Now in the main view call render actions with the required parameters. This will give you a nice composite view.
Why not have a service for this scenario to return a view model for you? That way you only have one dependency in the controller although your service may have the separate dependencies
the book dependency injection in .net suggests introducing "facade services" where you'd group related services together then inject the facade instead if you feel like you have too many constructor parameters.
Update: I finally had some available time, so I ended up finally creating an implementation for what I was talking about in my post below. My implementation is:
public class WindsorServiceFactory : IServiceFactory
{
protected IWindsorContainer _container;
public WindsorServiceFactory(IWindsorContainer windsorContainer)
{
_container = windsorContainer;
}
public ServiceType GetService<ServiceType>() where ServiceType : class
{
// Use windsor to resolve the service class. If the dependency can't be resolved throw an exception
try { return _container.Resolve<ServiceType>(); }
catch (ComponentNotFoundException) { throw new ServiceNotFoundException(typeof(ServiceType)); }
}
}
All that is needed now is to pass my IServiceFactory into my controller constructors, and I am now able to keep my constructors clean while still allowing easy (and flexible) unit tests. More details can be found at my blog blog if you are interested.
I have noticed the same issue creeping up in my MVC app, and your question got me thinking of how I want to handle this. As I'm using a command and query approach (where each action or query is a separate service class) my controllers are already getting out of hand, and will probably be even worse later on.
After thinking about this I think the route I am going to look at going is to create a SerivceFactory class, which would look like:
public class ServiceFactory
{
public ServiceFactory( UserService userService, CustomerService customerService, etc...)
{
// Code to set private service references here
}
public T GetService<T>(Type serviceType) where T : IService
{
// Determine if serviceType is a valid service type,
// and return the instantiated version of that service class
// otherwise throw error
}
}
Note that I wrote this up in Notepad++ off hand so I am pretty sure I got the generics part of the GetService method syntactically wrong , but that's the general idea. So then your controller will end up looking like this:
public class OrderController {
public OrderController(ServiceFactory factory) {
_factory = factory;
}
}
You would then have IoC instantiate your ServiceFactory instance, and everything should work as expected.
The good part about this is that if you realize that you have to use the ProductService class in your controller, you don't have to mess with controller's constructor at all, you only have to just call _factory.GetService() for your intended service in the action method.
Finally, this approach allows you to still mock services out (one of the big reasons for using IoC and passing them straight into the controller's constructor) by just creating a new ServiceFactory in your test code with the mocked services passed in (the rest left as null).
I think this will keep a good balance out the best world of flexibility and testability, and keeps service instantiation in one spot.
After typing this all out I'm actually excited to go home and implement this in my app :)
I'm designing medium-size website using asp.net mvc technology.
All business logic is organized into IServices (like IDomainService, IUserService, IAuthService, ITrainingService). All services are using IRepositories.
I'm using Ninject 1.5 to wire services with controllers and it seems working perfectly.
There is so far one subject I have no idea how to handle. Some services create contexts (per request) - for instance IDomainService creates DomainContext (per request) which is needed for IUserService.
ITrainingService is used only in TrainingController, which is accessible only by authorized users, and ITrainingService requires UserContext (also per request) to know who is having training.
This is my first project using IoC container.
Is there any design pattern or code-schema how to solve it?
I think I can fill context object using ActionFilters but how to manage their lifetime and where to put them to be accessible for IServices? (in an ellegant way)
I've used Ninject specifically in an MVC application. The way you'd accomplish this with Ninject is in the configuration or binding of your dependencies. When you do this, you specify how you want your object lifetimes to be managed. In most cases of a web app, you objects will be per request as you've indicated in your question.
One thing I've noticed in your question is that your DomainContext is being created by an IDomainService object and is used by other objects. If the domain service object is a sort of factory for a DomainContext, then you don't have much of a problem -- this becomes an exercise of how you configure Ninject to provide concrete objects and inject dependencies.
Here's general guidance on how you would structure your application -- bear in mind I don't have full understanding of your interfaces and classes:
public class GlobalApplication : NinjectHttpApplication {
protected override void RegisterRoutes(RouteCollection routes) {
// Your normal route registration goes here ...
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
// This function is resposible for creating a Ninject kernel. This is where
// the magic starts to happen.
protected override IKernel CreateKernel() {
var modules = new IModule[] {
new AutoWiringModule(),
new AutoControllerModule(
Assembly.GetExecutingAssembly()),
new ServiceModule()
};
return new StandardKernel(modules);
}
}
Note above that the easiest way to get Ninject to work is to derive your application class from the NinjectHttpApplication class. You will need to change your RegisterRoutes to an override method and will also be required to implement a method called CreateKernel. The CreateKernel method is responsible for returning the Ninject kernel which is itself the IoC container.
In the CreateKernel method, the Ninject-provided AutoControllerModule scans assemblies for MVC controller classes and registers them with the container. What this means is that dependencies on those controllers can now be injected by Ninject as it has become the controller provider for the application. The ServiceModule class is one that you need to create to register all of your services with Ninject. I'm guessing it would look something like this:
internal class ServiceModule : StandardModule {
public override void Load() {
Bind<IDomainService>()
.To<MyDomainService>()
.Using<OnePerRequestBehavior>();
Bind<DomainContext>()
.ToMethod( ctx => ctx.Kernel.Get<IDomainService>().CurrentDomainContext )
.Using<OnePerRequestBehavior>();
Bind<IService>()
.To<MyServiceType>()
.Using<OnePerRequestBehavior>();
}
}
Ninject's got a pretty expressive fluent interface for configuration. Note above that each statement basically associates a concrete class with an interface it implements. The "Using" phrase in the statement indicates to the Ninject kernel that the object will live for the life of the request only. So, for example, this means that anytime an IDomainService object is requested from the Ninject kernel during the same request, the same object will be returned.
As for you context objects, I'm taking a stab that your domain service creates these contexts and acts as a factory of sorts. In that regard, I bound instances DomainContext classes above to be produced by getting the value of the a property called CurrentDomainContext off the IDomainService. That's what the lambda above accomplishes. The nice thing about the "ToMethod" binding in Ninject is that you have access to a Ninject activation context object that allows you to resolve objects using the kernel. That's exactly what we do in order to get the current domain context.
The next steps are to ensure your objects accept dependencies properly. For example, you say that ITrainingService is used only in the TrainingController class. So, in that case I would ensure that TrainingController has a constructor that accepts an ITrainingService parameter. In that constructor, you can save the reference to the ITrainingService in a member variable. As in:
public class TrainingController : Controller {
private readonly ITrainingService trainingService;
public TrainingController(ITrainingService trainingService) {
this.trainingService = trainingService;
}
// ... rest of controller implementation ...
}
Remember that Ninject has already registered all of your controllers with the Ninject kernel, so when this controller is created and it's actions are invoked, you'll have a reference to the ITrainingService by way of the trainingService member variable.
Hope this helps you out. Using IoC containers can become quite confusing at times. Note, I highly recommend you check out the Ninject documentation -- it's a very well written introduction to Ninject as well as DI/IoC concepts. I've also left out discussion of the AutoWiringModule shown above; however, Nate Kohari (Ninject's creator) has a good write-up on his blog about this feature.
Good luck!
Im not exactly sure if I understand your problem completely, hopefully this bit of advice can help.
When using an IoC container you let the container handle object lifetime managment. I have only used Castle Windsor and StructureMap for dependency injection so I cant give you a concrete example for how to do this with Ninject.
Looking through the Ninject documentation I think you want to look at Activation Behaviours to specify object lifetime management.
Hope this helps.