Inside controller action you can:
MvcApplication app = this.HttpContext.ApplicationInstance as MvcApplication;
But this.HttpContext.ApplicationInstance only holds the superclass, not the derived class declared in Global.asax. Therefore any instance properties you declared there, are null;
Is there a way around this? Shouldn't there be a way to access the derived app class?
I'd like to have instances (of my helper classes), stored as instance properties inside the application instance, rather than having them as static classes.
Or do static helpers, hold no drawbacks?
There is a way around this and you've already written it:
MvcApplication app = this.HttpContext.ApplicationInstance as MvcApplication;
If you don't like that, try changing your MvcApplication class to:
public class MvcApplication : HttpApplication
{
public static MvcApplication Instance
{
get
{
// Current could be null, depending on the caller
return HttpContext.Current != null
? HttpContext.Current.ApplicationInstance
: null;
}
}
}
Then you can access your application as MvcApplication.Instance. Be cautious that Instance is not null.
Late answer (but for anyone in need of assistance).
I had this issue as well.
I think you can use the Application["myKey"] array, to set some values. Sure they aren't instance properties, but you can set a dependency injection container (like unity, who recommends this option in their code sample) , then access it from your controller with Application["myKey"].
From http://msdn.microsoft.com/en-us/library/ms178473%28VS.80%29.aspx
You should set only static data during application start. Do not set
any instance data because it will be available only to the first
instance of the HttpApplication class that is created.
There is no harm in using single static class, because your code becomes portable to non web project as well.
Ideally, instead of static properties, you can create MyApp class and wrap all app specific global data and other utility methods. And either you can create a static instance property and store instance of MyApp in HttpContext.Current.Application which is globally accessible in each request.
I think you are not aware that HttpApplication class is reused, and I suspect that your some handler is cleaning the properties.
Related
I am experiencing an issue, and I have come to a dead end on how to debug and resolve this.
I have an MVC application which is using Ninject for IoC and DI.
One of my dependencies is IApplicationLogger which I am currently implementing using Log4Net.
In my NinjectWebCommon I am binding my IApplicationLogger as follows:
kernel.Bind<IApplicationLogger>()
.ToMethod(ctx =>
{
string configFile = System.Configuration.ConfigurationManager.AppSettings["log4netconfigfilelocation"];
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(HttpContext.Current.Server.MapPath(configFile)));
var name = ctx.Request.Target.Member.DeclaringType.FullName;
var log4Netlogger = log4net.LogManager.GetLogger(name);
return new Log4NetApplicationLogger(log4Netlogger);
}).InTransientScope();
All fairly straight forward stuff.
However, I am finding that the first instance of IApplicationLogger which is activated is then passed to all constructors which require an IApplicationLogger instance.
for example I have the following
public class A : IA
{
public A(IB bclass, IC cclass, IApplicationLogger logger){}
}
public class B : IB
{
public B(IApplicationLogger logger){}
}
public class C : IC
{
public C(IApplicationLogger logger){}
}
I have set breakpoints on each constructor and also the line in my NinjectWebCommon kernel.Bind().ToMethod(ctx =>
What I see is this:
Break point in NinjectWebCommon is hit, and I can see
ctx.Request.Target.Member.DeclaringType.FullName is Class B.
Break point in Constructor Class B is hit and logger
instance is correct
Break point in Constructor Class C is hit, and
logger instance has a logger name of Type Class B
Break point in Constructor Class A is hit, and logger instance has a logger
name of Class B
I would expect the breakpoint within NinjectWebCommon to be hit for each new instance of IApplicationLogger that is required, but it is only hit once for the first activation for the instance of Class B.
I have tried my Binding without the InTransientScope() option.
My IA, IB and IC bindings are defined InSingletonScope(). This shouldn't cause an issue as I am expecting Ninject to activate an instance of each, each with it's own instance of IApplicationLogger.
The result of the binding I am seeing currently is that logging statements I output in say Class A are being recorded in the Log as being from a logger name for class of type B.
Can anyone suggest how I can diagnose why Ninject is reusing the TransientScoped() IApplicationLogger, or how I can peek under the hood of what Ninject is doing so that I can analyse this in greater detail?
For anyone interested I didn't discover the underlying issue here, but I have opted to inject an ILoggerFactory with a single method .GetLogger(string typename), allowing my classes to request their own Logger and passing their own Type name.
This way I can ensure that each Class has it's own logger, with the LoggerName matching the Class TypeName.
I'm just getting started with Unity, and I'm having trouble finding any advice about where to declare my UnityContainer object. Most of the examples that I've seen consist of just a single method where the UnityContainer object is declared at the top, then its mappings are defined, then a few object types are resolved. But how do you handle the container when you need to access it in several places throughout the program? For example, the user clicks on a button which opens a new window and that window needs a controller, which itself needs to resolve several services? I also want some of the services that Unity manages to be singletons, so wouldn't that mean that I'd have to have only a single instance of my UnityContainer throughout my program to manage those singletons?
My first thought is to have my main Program class have a static UnityContainer property or expose some sort of UnityContainerFactory class which manages a singleton UnityContainer instance, but both of those methods seem bad because they create a global property which a lot of things are dependent on.
What's the accepted way of doing this?
As noted in the other answer, you should compose the entire object graph in the Composition Root.
Don't declare the container as a static field since this would encourage developers to use it as a service locator which is an anti-pattern.
How to solve your problem?
Use Dependency Injection.
Here is an example for your special WinForms case:
In your Program.Main method, create the container, register the service (the dependency that you need to use from the other window) and then resolve the main form and run it like this:
UnityContainer container = new UnityContainer();
container.RegisterType<IService, Service>();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(container.Resolve<MainForm>());
In the MainForm, declare a dependency on a Func<SecondForm> where SecondForm is the form that you need to create from the main form when the button is clicked. Consider the following code inside your main form file:
public partial class MainForm : Form
{
private readonly Func<SecondForm> m_SecondFormFactory;
public MainForm(Func<SecondForm> second_form_factory)
{
m_SecondFormFactory = second_form_factory;
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SecondForm second_form = m_SecondFormFactory();
second_form.Show();
}
}
Please note that Func<SecondForm> acts as some kind of factory. I use it in this case because unity has a feature to support late construction of dependencies via Func.
The SecondForm has a dependency on IService like this:
public partial class SecondForm : Form
{
private readonly IService m_Service;
public SecondForm(IService service)
{
m_Service = sevice;
InitializeComponent();
}
//Use service here
}
You can now use IService from the second form.
Using Seemann words:
As close as possible to the application's entry point.
Give a look at http://blog.ploeh.dk/2011/07/28/CompositionRoot/ from the great Seemann.
I think that is totally acceptable for the main container to be a static field that get disposed together with your application, just remember to don't tie your classes to your container.
Get noticed of the so called "Service Locator" (again from Seemann: http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/)
Where to declare it really depends on the application, I'd go for the startup class of an owin application or the Main method of a console/WPF app.
I have a widely used cache interface in a web application with the implementation currently registered as SingleInstance.
This current cache implementation assumes single threaded initialization, but once initialized is immutable, so is safely shared across multiple threads.
However, this means that currently, if the underlying values change, the cache doesn't get updated until the application is restarted. While updating the underlying values is rare, we would now like to provide application behavior that modifies the underlying values, and then tells the cache to refresh.
I could modify the cache implementation to use locking, or perhaps utilize one of the .NET concurrent collections to safely update the cache values.
However, I'm wondering if autofac provides a capability that would allow me to change out the registered instance for a new instance on the next request, so that the cache implementation itself would not need to be modified.
So the ideal behavior would be, that when we modify the underlying values, we trigger the creation of a new cache instance. Once the instance is finished initializing, all in-progress requests continue with the old cache instance, any new http request scopes resolve to the updated instance.
Does autofac provide a built-in way to support this scenario?
You can never safely replace a singleton registered instance in your container. Once other singleton components depend on that, they will simply hold a reference to the old instance, and replacing the instance in the container means that some components (that will be created after the replace action) will refer to the new instance, while other components keep referring to the old instance. This will hardly ever lead to the behavior you like, and will most likely cause bugs.
My advice is never try to change your container's registrations, once the application is running. This will very quickly become quite complex to oversee whether the situation is correct and is thread-safe. For instance, what if you replace the instance at the time that the object graph for another thread is being resolved? It could mean that that object graph holds both a reference to the old and the new instance.
Instead, solve this problem at the application level. First of all, you need two APIs; one for reading the cache, and a second for updating the cache. Both can be implemented using the same component though:
// Very simplified version of what you actually might need
interface ICache { CacheObject Get(); }
interface ICacheUpdater { void Set(CacheObject o); }
A simplistic implementation could look like this:
sealed class Cache : ICache, ICacheUpdater
{
private static CacheObject instance;
public void Set(CacheObject o) => instance = o;
public CacheObject Get() => instance;
}
This implementation might work, but if the cache is retrieved multiple times within the same request, it's possible to read both the old and the new values within the same request (since a different thread can call Set in between). This might be a problem. In that case, you can change the implementation to the following:
sealed class HttpCache : ICache, ICacheUpdater
{
private static readonly object key = typeof(HttpCache);
private static CacheObject instance;
private static IDictionary items => HttpContext.Current.Items;
public void Set(CacheObject o) => instance = o;
public CacheObject Get() => (CacheObject)items[key] ?? (items[key] = instance);
}
In this implementation an extra reference to the cache object is stored in the HttpContext.Items dictionary. This ensures that during the execution of a single (web) request, always the same instance is retrieved.
This example assumes you are running a web application, but you can easily imagine a solution for a different application type.
To update a component registered as a single instance, you can have a registration like this :
builder.RegisterType<ServiceProvider>().SingleInstance();
builder.Register(c => c.Resolve<ServiceProvider>().Service).As<IService>();
and ServiceProvider like this :
public class ServiceProvider
{
public ServiceProvider()
{
this.Service = new Service();
}
public IService Service { get; set; }
}
To update the instance you only have to do that :
container.Resolve<ServiceProvider>().Service = newInstance;
The second part of the question may be more difficult :
Once the instance is finished initializing, all in-progress requests continue with the old cache instance, any new http request scopes resolve to the updated instance.
What you want is to inject a single instance registration in a specific scope. To make this, you can use the ChildLifetimeScopeBeginning event to set the instance for the whole life of scope.
builder.RegisterType<ServiceProvider>().Named<ServiceProvider>("root").SingleInstance();
builder.RegisterType<ServiceProvider>().InstancePerRequest();
builder.Register(c => c.Resolve<ServiceProvider>().Service).As<IService>();
IContainer container = builder.Build();
container.ChildLifetimeScopeBeginning += (sender, e) =>
{
ServiceProvider scopeServiceProvider = e.LifetimeScope.Resolve<ServiceProvider>();
ServiceProvider rootServiceProvider = container.ResolveNamed<ServiceProvider>("root");
scopeServiceProvider.Service = rootServiceProvider.Service;
};
To change the global IService instance you will have to resolve the "root" named ServiceProvider
scope.ResolveNamed<ServiceProvider>("root").Service = newInstance;
and to change the scope only IService instance you will resolve a normal ServiceProvider
scope.Resolve<ServiceProvider>().Service = newInstance;
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")
In my MVC3 app I have an IDataRepository interface which is referenced by all my controllers to give them access to the data layer. There's also a DataRepository class which is implements IDataRepository for a particular data source (an nHydrate-derived Entity Framework, in my case). The DataRepository class takes a single argument, which is the connection string to the underlying database.
I've been successfully using nInject to to IoC with the controller classes using the following binding:
kernel.Bind<IDataRepository>()
.To<DataRepository>()
.WithConstructorArgument("connectionString", DataRepositoryBase.GetConnectionString());
Today I read about nInject scoping, and I thought it would be useful to arrange things so that only one instance of DatabaseRepository got created for each request (I'm thinking this will be more efficient, although with EF I'm not sure).
Unfortunately, I can't seem to figure out how to implement the pattern correctly. For example, this doesn't work:
kernel.Bind<DataRepository>()
.ToSelf()
.InRequestScope()
.WithConstructorArgument("connectionString", DataRepositoryBase.GetConnectionString());
kernel.Bind<IDataRepository>()
.To<DataRepository>();
My thinking was that this would create just a single instance of DataRepository, which would be used in all references to IDataRepository. The error message complained that no match could be found for the connectionString parameter, and DataRepository was not self-bindable. I tried some variations, but when I could get it to work the singleton pattern wasn't being followed (i.e., I could see in the debugger that multiple instances of DataRepository were being created).
I'm missing something obvious here :).
--- Addendum ---
Unfortunately, the suggestion doesn't prevent multiple instances from being created within the same request.
To be clear, what I tried was:
public class BaseControllerModule : NinjectModule
{
public override void Load()
{
Bind<IDataRepository>().To<DataRepository>().InRequestScope()
.WithConstructorArgument("connectionString", DataRepositoryBase.GetConnectionString());
}
}
and what I was monitoring was the constructor:
public DataRepository( string connectionString )
: base(connectionString)
{
}
-- More info #2 --
Here's the layout of the classes Ninject is resolving for me:
public class DataRepositoryBase
{
protected DataRepositoryBase( string connectionString )
{}
public static string GetConnectionString() {}
}
public class DataRepository : DataRepositoryBase, IDataRepository
{
public DataRepository( string connectionString )
: base(connectionString)
{}
}
I've left out the implementation details, but hopefully this paints a better picture.
Looking this over, I wonder if I'm causing problems by making connectionString a constructor parameter for both DataRepository and its base class DataRepositoryBase. Wouldn't Ninject resolve connectionString in the call the base class constructor?
p.s. I belatedly realized I don't need DataRepositoryBase, because its functionality can be merged into DataRepository. I've done that, but I'm still having the constructor for DataRepository called multiple times in what appears to be one request.
p2.s. For fun, I tried declaring InSingletonScope() in the Ninject binding definition. That worked -- the constructor for DataRepository now only gets called once, when the app is first accessed. But I don't think it's a good idea to have singletons in an MVC app. It seems like that would cause the "state" of the app to get "locked" in memory.
--- yet more info ---
The problem seems to be with the way I've designed my MVC app. What I assumed was a single request from the browser back to the server often results in multiple requests being processed in sequence (I'm watching the BeginRequest event being fired in the MvcApplication class). It seems like every time I transition to a different controller a new request is being generated (e.g., via a RedirectToAction). I guess this makes sense, but it means Ninject's InRequestScope won't quite do what I want.
But it also makes me wonder if I've just designed the app wrong. It seems like I should be grouping all of the action methods that might get invoked on a browser call into a single controller. Instead, I've organized the action methods by how they fit into the conceptual model for my app.
These two bindings say:
When a DataRepository is requested reuse the instance for all occurances within the request and set the connection string to DataRepositoryBase.GetConnectionString().
But when a IDataRepository is requested, create a new instance for every occurance and let Ninject decide what it injects for the connection string.
What you really want is done by adding InRequestScope to the first code snippet.
Wouldn't that be sufficient to have a singleton?
kernel.Bind<IDataRepository>()
.To<DataRepository>()
.InSingletonScope()
.WithConstructorArgument("connectionString", DataRepositoryBase.GetConnectionString());
RequestScope is not a singleton, it means that the objects are separate for each user's call.
By the way, I think the real repository shouldn't be singleton - it should rather follow the Unit of Work pattern, meaning that its lifetime should represent one higher-level data operation and the connection itself should be at lower level than repository.