I've been looking through examples and documentation for Autofac, and can't see to get this working.
We have a helper class, Core.Helpers.Tokens with a property set up like this:
namespace Core.Helpers
{
public static class Tokens
{
private static IConfigurationManager ConfigurationManager;
public static string GetToken()
{
var sessionTokenName = ConfigurationManager.GetAppSetting("SessionTokenName");
return (string) HttpContext.Current.Session[sessionTokenName];
}
}
}
The configuration is designed like this:
namespace Core.Config
{
public interface IConfigurationManager
{
//...
}
public class WebConfigConfigurationManager : IConfigurationManager
{
//...
}
}
In our MVC Web app (which references and uses Core.Helpers, Startup.cs I'm trying to register IConfigurationManager for property injection.
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
// REGISTER CONTROLLERS SO DEPENDENCIES ARE CONSTRUCTOR INJECTED
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterModule<AutofacWebTypesModule>();
builder.RegisterFilterProvider();
builder.RegisterType<WebConfigConfigurationManager>().As<IConfigurationManager>().PropertiesAutowired();
RegisterTypes(builder);
// BUILD THE CONTAINER
var container = builder.Build();
var webConfig = container.Resolve<IConfigurationManager>();
// REPLACE THE MVC DEPENDENCY RESOLVER WITH AUTOFAC
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// REGISTER WITH OWIN
app.UseAutofacMiddleware(container);
app.UseAutofacMvc();
}
When the web code calls GetToken, ConfigurationManager is null. What am I missing?
One error is that your Tokens.ConfigurationManager is a private field, whereas property injection works with public properties.
Also, it must be an instance property, not static. So in the end it should be
public IConfigurationManager ConfigurationManager{get;set;}
But that would mean you'd also have to inject a Tokens instance, and that would make no longer a static helper class, you'll have to do some redesign, there are some options:
If you have an IConfigurationManager instance everywhere you expect to call GetTokens from you can pass that in as an input parameter to GetTokens()
You promote this static helper to a dependency (e.g. ITokenService ? ) that will be injected to everywhere it's needed. Instead of making it static,
you can use Autofac lifetime management to make it a singleton. (Probably the best solution)
The worst solution, but the smallest change, one that works without having to give up this being a static helper class, is to make the property use the DependencyResolver instead of injection, something like:
private static IConfigurationManager ConfigurationManager{ get { return DependencyResolver.Current.GetService();} }
You are resolving IConfigurationManager, You should be resolving WebConfigConfigurationManager.
If you have 5 classes that utilize IConfigurationmanager, resolving the interface does not tell autoface which concrete class you are wanting to utilize which has this interface.
Related
I have an ASP.NET Web API project using ASP.NET Identity for authentication/authorization. I've inserted my own custom Identity implementation, namely my own UserStore to talk with Azure Tables, and removed the EF/SQL Server stuff. However, most of the docs I see out there recommend creating an instance of the UserManagerFactory within the Startup.Auth.cs class as follows:
public static Func<UserManager<CustomIdentityModel>> UserManagerFactory { get; set; }
UserManagerFactory = () => new UserManager<CustomIdentityModel>(new CustomUserStore<CustomIdentityModel>());
My CustomUserStore has a dependency on a repository in another project, which I dependency inject into the constructor.
private readonly IRepository _repo;
public CustomUserStore(IRepository repo)
{
_repo = repo;
}
However, creating a "new CustomUserStore()" in the Startup.Auth.cs is an anti-pattern and cannot resolve the dependency. What is the right way to resolve this dependency when creating a UserManager? I'd like to either not have to "new up" a UserManagerFactory, or somehow resolve the dependency inline:
new UserManager<CustomUserModel>(container.Resolve<IRepository>());
Then the question becomes, how to get the single IOC container instance...
Create an static field in your global.asax or owin startup class to hold a reference for ioc container, in your container bootstrap setup set the static field value.
after that you can access the ioc container from somewhere, in your Startup.Auth.cs class you can read the ioc static field container and initialize inline UserStore.
Owin Class:
public class Startup {
public static IUnityContainer Container; //Static field for hold ioc container reference.
public void Configuration(IAppBuilder app)
{
//Code Omitted for brevity
Container = YourIoCContainerReference:
}
}
}
So you can do an inline initialization:
var repository = Startup.Container.Resolve<IRepository>();
and get your dependency.
In trying to configure ServiceStack.net to use Ninject as its IOC, I am getting errors referring to various bindings not being defined. Primarily for ICache Client.
What specific bindings need to be created to use Ninject properly?
Currently have specified:
Bind<ISessionFactory>().To<SessionFactory>();//Is this correct/needed?
Note
I have created an IContainerAdapter as per the ServiceStack documention to implement the use of Ninject.
(Found here:ServiceStack IOC Docs)
Note 2
My apphost configure method looks like this:
public override void Configure(Funq.Container container)
{
IKernel kernel = new StandardKernel(new BindingModule());
container.Adapter = new NinjectContainerAdapter(kernel);
}
Note 3
I have registered the ICacheClient as follows:
Bind().To();
And I am now getting an error pointing to IRequest
Error activating IRequestLogger\nNo matching bindings are available, and the type is not self-bindable
Container Adapter
public class NinjectContainerAdapter : IContainerAdapter
{
private readonly IKernel _kernel;
public NinjectContainerAdapter(IKernel kernel)
{
this._kernel = kernel;
}
public T TryResolve<T>()
{
return this._kernel.Get<T>();
}
public T Resolve<T>()
{
return this._kernel.Get<T>();
}
}
Have you injected your Container adapter with:
container.Adapter = new NinjectIocAdapter(kernel);
If so, try also make your AppHost class internal if you haven't done so. There should only be 1 instance of AppHost and some IOC's like to create their own instance, wiping out all the configuration from the first one.
The behavior you're getting sounds like Ninject is complaining about unresolved dependencies. Make sure you get Ninject to return null with Unresolved dependencies by using kernal.TryGet<T> in your Container Adapter, e.g:
public T TryResolve<T>()
{
return this._kernel.TryGet<T>();
}
You need to write your own IContainerAdapter and then set Container.Adapter in your AppHost
I've run into an interesting design issue with a class library I am writing. I have a custom implementation of the AuthorizeAttribute that I want clients to be able to use like this:
[Protected("permission_name")]
In the above code, PermissionAttribute inherits from AuthorizeAttribute and uses a local default (DefaultContext created using HttpContext).
Behind the scenes, the attribute uses a SecurityService to check users, roles and permissions against (the SecurityService itself uses a client-provided persistence service that they can wire up in the composition root of their app).
So my attributes need a reference to the SecurityService to function. Since Attribute constructors can only have compile-time constants, I cannot use constructor injection.
I don't want to force my clients to use a DI framework - they should be able to discover and wire up the necessary dependencies in their composition root without using an IoC library, if they so choose.
Here are my options:
Have the library use a singleton SecurityService.
Use property injection, which would work but
it would make the dependency seem optional, which it is not and
I don't know where I can do property injection in an MVC app on an authorize attribute.
A possible solution to 2. above is to do set an instance of SecurityService as a static property on the attribute at application startup and use a guard clause to prevent it from being set more than once, like this:
class ProtectedAttribute : ...
{
private static ISecurityService _SecurityService ;
public static ISecurityService SecurityService
{
get
{
return _SecurityService ;
}
set
{
if (_SecurityService != null)
throw new InvalidOperationException("You can only set the SecurityService once per lifetime of this app.") ;
_SecurityService = value ;
}
}
}
The SecurityService could be an abstract service facade so that it can be extended/replaced by a different implementation.
Is there a better way to solve this problem?
UPDATE: Adding some code to show how I am going to do it:
Add a public property on the attribute that returns the permission name:
public class ProtectedAttribute : ...
{
private string _Permission ;
public string Permission { get { return _Permission ; } /*...*/ }
public ProtectedAttribute(string permission) { /*...*/ }
}
Setup an authorization filter and configure dependency via Ninject (if using Ninject):
using Ninject.Web.Mvc.FilterBindingSyntax;
public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
// mySecurityService instance below can have a singleton lifetime - perfect!
this.BindFilter<MyAuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<ProtectedAttribute>()
.WithConstructorArgument("securityService", mySecurityService)
.WithConstructorArgumentFromActionAttribute<ProtectedAttribute>("permission", p => p.PermissionName) ;
}
}
Ohhh it's...beautiful sniffle
With ASP.NET MVC 3 you could use constructor injection with action filters thanks to the new IFilterProvider. This way you no longer need to decorate your controller actions with action filters. You could apply them thanks to this interface and using a marker attribute.
And if you don't wanna bother implementing it manually you could always use an existing DI framework such as Ninject which provides a fluent way to define action filter dependencies.
My applications inherit from a base Application class that exposes the IOC container.
public interface IInjectableApplication
{
IUnityContainer Container { get; }
}
Then I have a base attribute class, which is aware of this
public abstract IocAwareActionFilterAttribute : ActionFilterAttribute{
protected T ResolveItem<T>(ResultExecutedContext context)
{
var app = context.HttpContext.ApplicationInstance as IInjectableApplication;
if (app == null) { throw new NullReferenceException("Application is not IInjectable."); }
T c = (T)app.Container.Resolve(typeof(T));
if (c == null) { throw new NullReferenceException(string.Format("Could not find injected {0}.", typeof(T).FullName)); }
return c;
}
}
While this is not true Injection, since Attributes aren't constructed 'normally', this provides a similar behavior. No reason it should not be adaptable to other IOCs
I have configured Unity in my ASP.NET application and the configuration is loaded when the first request is received in Application_BeginRequest. then the Unity container is stored in the Global.ascx as a property so that my other class can access it:
public static IUnityContainer ContainerHolder { get; set; }
IUnityContainer IContainerAccessor.Container
{
get { return ContainerHolder; }
}
ContainerHolder, holds the container instance across application and Container property allows access to this property in each session.
Then I have a UnityLocator class which enables me access this property across the application:
public static class UnityLocator
{
private static IUnityContainer Container
{
get
{
return ((IContainerAccessor)HttpContext.Current.ApplicationInstance).Container;
}
}
}
Everything works fine!
I have also a method to access the instance from Unity:
UnityLocator.GetInstance<IThemeManager>();
protected Repository(ICustomCacheManager customCacheManager)
{
this.Cache = customCacheManager;
}
protected Repository()
: this(UnityLocator.GetInstance<ICustomCacheManager>())
{
}
this has been used in my app so that I can retrieve an existing instance from Unity so that I can inject it to other classes. For example my view (asp.net page) injects this to its Presenter class as a dependency.
Now, I'd like to configure my Unit tests to run.
How could I do that?! global.ascx doesn't exist there obviously so I thought I should create a BaseTest class and let all my tests inherit it. then at the constructor of this BaseTest class, I build up my instances. Is it the right way to do it?
How to configure unit tests with Unity now?
Thanks
UPDATE:
UnityLocator.GetInstance added.
You shouldn't worry about accessing your IoC container. That is a violation of Unit Tests.
Unit tests you should not worry about any concrete implementation or dependency (other than the class under test).
To me, having your IoC globally available is a bad design choice. You should have your dependencies injected via properties or constructors.
Probably using the global application class for storing the service locator was not a good idea. Why don't you use the built-in ServiceLocator class? It is available from anywhere in the code and doesn't depend on global application / HttpContext.
Whether or not using the container in unit tests is another story. Personally I am not against it as long as you put stub implementations of your services into the container.
Edit: the way to configure your container using ServiceLocator:
private void ConfigureUnity()
{
UnityServiceLocator locator = new UnityServiceLocator( ConfigureUnityContainer() );
ServiceLocator.SetLocatorProvider( () => locator );
}
private IUnityContainer ConfigureUnityContainer()
{
IUnityContainer container = new UnityContainer();
// this loads container's configuration, comment or uncomment
container.LoadConfiguration();
return container;
}
You can then access the container from within the locator like:
var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
In your page, try doing things like this:
public class DepartmentReportPage : Page
{
private readonly DepartmentReportPresenter _presenter;
public DepartmentReportPage()
{
this._presenter =
UnityLocator.GetInstance<DepartmentReportPresenter>();
this._presenter.View = this;
}
}
I have the following classes / interfaces:
public interface IProjectRepository
{
IQueryably<Project> GetProjects();
}
// Depends on my EF Context
public ProjectRepository : IProjectRepository
{
private MyDbEntities context;
public ProjectRepository(MyDbEntities context)
{
this.context = context;
}
public IQueryable<Project> GetProjects()
{
return context.Projects;
}
}
My controller:
// Depends on IProjectRepository
public class ProjectsController : Controller
{
private IProjectRepository projectRepository;
public ProjectsController(IProjectRepository projectRepository)
{
this.projectRepository = projectRepository;
}
public ActionResult Index()
{
return View(projectRepository.GetProjects());
}
}
I need to set up my dependency injection so that it passes in ProjectRepository into my Controller AND it needs to pass in my Entity Framework context into the Project Repository. I need to Entity Context to be HTTP Request scoped.
I'm not sure where I am supposed to put all the mapping code to make the dependency injection work. I also don't understand how MVC will work without the default constructor.
Can someone help me put all the pieces together? I am using StructureMap but I could easily switch to something else because I have no idea what I'm doing.
If you are using MVC 3, to do things properly, you should make use of the built in dependency resolution bits. I would highly recommend you read through the series of blog posts from Brad Wilson (member of the ASP.NET MVC team).
As far as a StructureMap specific implementation, I found the following blog posts helpful.
StructureMap and ASP.NET MVC 3 – Getting Started
StructureMap, Model Binders and Dependency Injection in ASP.NET MVC 3
StructureMap, Action Filters and Dependency Injection in ASP.NET MVC 3
StructureMap, Global Action Filters and Dependency Injection in ASP.NET MVC 3
Anyway, here's some code. To start with, I would suggest that you install the StructureMap-MVC3 NuGet package.
I can't remember what exactly it creates in the way of files, but here's what's basically involved.
/App_Start/StructuremapMvc.cs - This hooks into the Application_Start and sets up your container (SmIoC.Initialize()) and then sets the MVC 3 DependencyResolver to a your SmDependencyResolver
using System.Web.Mvc;
using YourAppNamespace.Website.IoC;
using StructureMap;
[assembly: WebActivator.PreApplicationStartMethod(typeof(YourAppNamespace.App_Start.StructuremapMvc), "Start")]
namespace YourAppNamespace.Website.App_Start {
public static class StructuremapMvc {
public static void Start() {
var container = SmIoC.Initialize();
DependencyResolver.SetResolver(new SmDependencyResolver(container));
}
}
}
/IoC/SmDependencyResolver.cs - this is your MVC 3 IDependencyResolver implementation. It's used in the App_Start code above.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using StructureMap;
namespace YourAppNamespace.Website.IoC
{
public class SmDependencyResolver : IDependencyResolver
{
private readonly IContainer _container;
public SmDependencyResolver(IContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
if (serviceType == null)
{
return null;
}
try
{
return _container.GetInstance(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.GetAllInstances(serviceType).Cast<object>(); ;
}
}
}
/IoC/SmIoC.cs - this is where you setup your container... also used in the App_Start code.
namespace YourAppNamespace.Website.IoC
{
public static class SmIoC
{
public static IContainer Initialize()
{
ObjectFactory.Initialize(x =>
{
x.For<IProjectRepository>().Use<ProjectRepository>();
//etc...
});
return ObjectFactory.Container;
}
}
}
Now everything is hooked up... (I think ;-) but you still have one last thing to do. Inside your Global.asax, we need to make sure you dispose of everything that is HttpContext scoped.
protected void Application_EndRequest()
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
So you should be able to achieve dependency injection through constructor injection, which is the correct way to go about doing things.
If you are set on using StructureMap, here is a tutorial on the setup that you will probably need.
Some other dependency injection frameworks come with custom controller factories which will do that for you. Ninject (open source dependency injection), for example has an extension that you can use that contains this behaviour. See here for example. And here to the extension.
You can use also Unity IOC which is another popular dependency injection framework with which, to my knowledge, you will have to create a custom controller factory (like with structuremap) to achieve this behaviour. See here for an example.
You can also research all other dependency injection frameworks to see what support you can get with each.
EDIT:
I hope I am explaining this correctly but here is some background info.
MVC uses a controller factory that has the responsibilities of instantiating the respective controllers needed when a request is made. By default, it will initialize a controller by calling its parameterless constructor.
To create the infrastructure for the constructor parameter injection you need to create a custom factory that can resolve constructor parameters. That is where the dependency injection containers come in: essentially the DI container (if configured properly) knows how to resolve those dependency and your custom factory will leverage it to request the registered dependencies and pass the to the controller constructor.
All work pretty much the same. Historically, all have had setter injectors (set up a property that is then filled), but most have constructor injection now. In structure map, the easiest way to accomplish this is use the attribute: [StructureMap.DefaultConstructor].
Once you add the attribute, the objects you have placed in your "map" should inject without any extra work. If you can't use attributes, consider using the setter.
There is a file on the structure map site:
http://structuremap.net/structuremap/ConstructorAndSetterInjection.htm
When using StructureMap I would generally have something like this in my controller:
private static IProjectRepository GetProjectRepository()
{
var retVal = ObjectFactory.TryGetInstance<IProjectRepository>()
?? new ProjectRepository();
return retVal;
}
If the TryGetInstance returns null (because nothing was set for that type) it will default to the concrete type you specify.
Now you have a bootstrapper somewhere like this:
public static class StructureMapBootStrapper
{
public static void InitializeStructureMap()
{
ObjectFactory.Initialize(x =>
{
x.For<IProjectRepository>().Use<ProjectRepository>();
}
}
}
Now you call this bootstrapper in your Global.asax Application_Start event:
protected void Application_Start()
{
StructureMapBootStrapper.InitializeStructureMap();
}
Now in a test project, when you want to inject a mock repository you can just do this:
[TestMethod]
public void SomeControllerTest()
{
StructureMap.ObjectFactory.Inject(
typeof(IProjectRepository),
new MockProjectRepository());
// ... do some test of your controller with the mock
}