How to configure Ninject to work with ServiceStack.net - c#

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

Related

Property Injection with Autofac isn't working

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.

How to link Autofac to UnitTesting

Within my Web API I have linked Autofac as IoC container, and I do it like this:
Domain level
public class Autofac
{
protected ContainerBuilder Builder { get; set; }
public Autofac()
{
this.Builder = new ContainerBuilder();
}
public virtual IContainer Register()
{
// Register dependencies
SetUpRegistration(this.Builder);
// Build registration.
var container = this.Builder.Build();
// End
return container;
}
private static void SetUpRegistration(ContainerBuilder builder)
{
// === DATALAYER === //
// MyRepository
builder.RegisterType<MyRepository>()
.As<IMyRepository>()
.InstancePerLifetimeScope();
// === DOMAIN === //
// MyManager
builder.RegisterType<MyManager>()
.As<IMyManager>()
.InstancePerLifetimeScope();
}
}
Web API
public class Autofac : Domain.IoC.Autofac
{
public IContainer Register(HttpConfiguration config)
{
// Register your Web API controllers.
base.Builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// OPTIONAL: Register the Autofac filter provider.
base.Builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);
// Complete registration and get container instance.
var container = base.Register();
// Set the dependency resolver to be Autofac.
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// Done.
return container;
}
}
As you see it inherits from the base class from Domain and sets up Web API specific config.
Usage
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
new IoC.Autofac().Register(GlobalConfiguration.Configuration);
}
Which is at global.asax, as you know.
The question
This works fine for Web API, but I haven't got a clue what I need to do to register all this within a UnitTest project context.
The idea is that I would create a similar implementation to the Autofac class at Web API level, but than with mocks (completely ignoring the base class from Domain).
Any pointers?
Personally I never see the need (and I struggle to comprehend how viable or helpful it would be) to setup my IoC container directly within a unit test.
As a unit test is used to test a logical piece of code that can be quickly built, easily ran and doesn't require much (I'd advocate no) tear-down. It should not require all of your application to be be setup for the test to run.
Remember that your unit test is simply testing the flow of data through the system i.e that your DomainManager is actually going to call a IRepository when you expect that it should. Then you would have separate test classes for all your repositories to determine that they would correctly add to the database etc.
I'm not sure how you use the DBContext class but as an example of a wrapper this is what it would sort of look like.
interface IDBSetWrapper
{
object Add(object entity);
}
interface IDBContextWrapper
{
...
IDBSet Set(Type entityType);
...
}
class DBContextWrapper : IDBContextWrapper
{
private readonly DBContext context;
public DBContextWrapper()
{
context = new DBContext();
}
...
public IDBSet Set(Type entityType)
{
var dbSet = context.Set(entityType);
return new DBSetWrapper(dbSet);
}
...
}
It's not much but I hope that it demonstrates what I mean about a thin wrapper. Basically the wrapper is the DBContext and will contain an instance of it within the class, the actual DBContext will be called when you request the wrapper to do anything.
I have shown what would happen when returning another object (in this case a DBSet), this will also be wrapped in a separate object with an interface. This is so that you can mock the returns from this class easily.
You can add this new wrapper into your IoC a little better now as it provides an interface.
One thing to note is that you won't be able to and probably wouldn't wish to test the wrapper class, there would be very little point as I see it. But previously I've seen colleagues do an integration test on these sort of classes.

using a Handler in Web API and having Unity resolve per request

I am using Unity as my IoC framework and I am creating a type based on the value in the header of each request in a handler:
var container = new UnityContainer();
container.RegisterType<IFoo,Foo>(new InjectionConstructor(valuefromHeader));
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityDependencyResolver(container);
The problem is that the handler's SendAsync means that the global container is getting overwritten by different requests and the controllers that use IFoo in their constructor are getting the wrong values.
1) Can I make the SendAsync sync?
2) If not, how do I create different instances for each request and have the IoC container resolve safely?
I have looked at the following articles without success:
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
http://www.strathweb.com/2012/11/asp-net-web-api-and-dependencies-in-request-scope/
http://benfoster.io/blog/per-request-dependencies-in-aspnet-web-api-using-structuremap
Thanks in advance.
I agree with #Steven's approach, but that doesn't answer your more general question of how to resolve per request.
I would recommend you change to using the UnityHierarchicalDependencyResolver and then anything you register with HierarchicalLifetimeManager will be resolved per request.
Change this...
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityDependencyResolver(container);
to this...
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityHierarchicalDependencyResolver(container);
The problem you are having is caused by you mixing runtime values with design time dependencies. In general, the services you resolve from the container should not depend on runtime values in their constructor. You shouldn't do this, because components tend to live much longer than runtime values and injecting runtime values into components, makes it much harder to diagnose and verify the container's configuration.
Instead, hide that value behind a service that can provide consumers with that instance when required. For instance:
public interface IHeaderValueProvider
{
HeaderValue GetCurrentValue();
}
You can create an implementation that can be easily registered and injected into any component that needs that value. Anytime after the construction phase, those components can call the GetCurrentValue() method on the injected IHeaderValueProvider dependency.
I managed to resolve per request by declaring my custom UnityResolver's class within the WebApiConfig class. The UnityResolver class uses the HttpConfiguration class assuming you're using an OWIN context.
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var _container = new UnityContainer();
DependencyConfiguration.ConfigureContainer(_container);
config.DependencyResolver = new UnityResolver(_container);
}
The ConfigureContainer class is simply a class where I declare my IOC dependencies as shown below:
private static void RegisterReleaseEnv(IUnityContainer container)
{
//Repository Registration
container
.RegisterType(typeof(IRepository<>), typeof(GenericRepository<>), new HierarchicalLifetimeManager());
}
It is very important that you use the HierarchicalLifetimeManager lifetime manager so that you get a new instance per request.
The UnityResolver class then looks like this:
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
container.Dispose();
}
}
I hope this helps.
For more information: http://www.asp.net/web-api/overview/advanced/dependency-injection

How to pass IoC container to NancyFX? (OWIN, Unity)

I have a Windows service where I use OWIN and NancyFX to host a website on top of it. On many places in my service, I use Unity to inject dependencies into classes, mostly services. However, if I use them in any Nancy modules, the dependencies get resolved twice because Nancy uses its own IoC container (TinyIoC).
Fortunately, Nancy allows to override the default IoC container generation and use of an existing one by creating a nancy bootstrapper. But how do I pass my existing IUnityContainer to the bootstrapper?
Basically, all I have to start OWIN is...
WebApp.Start<MyOwinStarter>(url);
How can I pass a Unity container to it to pass it further to the nancy bootstrapper?
#ccellar got me into the right direction.
I created a static class UnityHelper with the following methods:
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => {
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unityConfiguration");
return new UnityContainer().LoadConfiguration(section);
});
public static IUnityContainer GetConfiguredContainer() {
return container.Value;
}
Created a custom NancyBootstrapper class:
public NancyBootstrapper(IUnityContainer container) {
if(container == null)
throw new ArgumentNullException("container");
this._unityContainer = container;
}
protected override IUnityContainer GetApplicationContainer() {
return _unityContainer;
}
and passed the container to the bootstrapper in my web app startup class:
appBuilder.UseNancy(new NancyOptions {
EnableClientCertificates = true,
Bootstrapper
= new NancyBootstrapper(UnityHelper.GetConfiguredContainer())
});
Neat!
Disclaimer: I really don't know if this is the best/cleanest/whatever solution to this problem. But for me it works.
I wrapped my container (Castle Windsor) like this, which is basically a singleton.
public class Container
{
// static holder for instance, need to use lambda to construct since constructor private
private static readonly Lazy<IWindsorContainer> instance = new Lazy<IWindsorContainer>(() =>
{
var container = new WindsorContainer();
container.Install(FromAssembly.This());
return container;
});
// private to prevent direct instantiation.
private Container()
{
}
// accessor for instance
public static IWindsorContainer Instance
{
get
{
return instance.Value;
}
}
}
Then in my custom bootstrapper I access the already configured container like this
protected override Castle.Windsor.IWindsorContainer GetApplicationContainer()
{
return Container.Instance;
}
Actually, the easiest and correct way, would be to inherit a new bootstrapper class from the Bootstrapper type you are using - in your case WindsorNancyBootstrapper and override the GetApplicatioContainer method and return your instance
You can read more about it here
https://github.com/NancyFx/Nancy.bootstrappers.windsor#customizing

How to configure unit tests with an IoC container in ASP.NET?

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;
}
}

Categories

Resources