Property injection not working when using StructureMap and NServiceBus - structuremap

I've installed the NServiceBus.StructureMap package from NuGet and property injection is no longer working on my Sagas. Here's my configuration code (using the generic host):
public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
public void Init()
{
Configure.With()
.StructureMapBuilder(ConfigureStructureMap())
.XmlSerializer();
}
private static IContainer ConfigureStructureMap()
{
ObjectFactory.Initialize(cfg =>
{
cfg.For<IBarcodeReader>().Use<DataMatrixBarcodeReader>();
cfg.ForSingletonOf<IDocumentStore>().Use(() => InitializeStore());
cfg.For<IDocumentSession>().Use(x => x.GetInstance<IDocumentStore>().OpenSession());
});
return ObjectFactory.Container;
}
private static IDocumentStore InitializeStore()
{
return new DocumentStore
{
Url = "http://localhost:8080/",
DefaultDatabase = "db"
}
.Initialize();
}
}

Setter injection is not on by default in StructureMap so you need to enable it Autowire setters using StructureMap

Related

Using Unity with Web Api 2 gives error does not have a default constructor

I have ASP.NET MVC5 web application and i also have Web API in the same application. I am uisng Unity (version 4) for DI.
I am configuring the Unity container on APP start as below
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
UnityConfiguration.Config();
}
}
public class UnityConfiguration()
{
public void Config()
{
UnityContainer container = new UnityContainer();
container.RegisterType<IMyService, Myservice>();
container.RegisterType<IGenericRepository, GenericRepository>();
container.RegisterType<DbContext, MyEntities>();
}
}
public class GenericRepository:IGenericRepository
{
private DbContext _dbcontext;
public GenericRepository(DbContext dbcontext)
{
_dbcontext = dbcontext;
}
}
public class MyService:IMyService
{
private IGenericRepository _repo;
publi void MyService(IGenericRepository repository)
{
_repo = repository;
}
}
public class MyApiController:ApiController
{
provate IMyService _service;
MyApiController(IMyService myservice)
{
_service = myservice;
}
public IEnumerable<MyModel> GetData()
{
var result = _service.GetData();
return result.ConvertToMyModel();
}
}
However when i call the url like
localhost://lookup/getdata
I get error
Type 'LookupController' does not have a default constructor
How do i solve this issue? Do i need to register each controller i create with Unity or Unity automatically registers all MVC controllers?
I tend to use the Unity.Mvc-package.
You do not need to register the controllers, but you need to register Unity with WebAPI.
public class UnityConfiguration()
{
public IUnityContainer Config()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IMyService, Myservice>();
container.RegisterType<IGenericRepository, GenericRepository>();
container.RegisterType<DbContext, MyEntities>();
// return the container so it can be used for the dependencyresolver.
return container;
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Your routes...
// Register Unity with Web API.
var container = UnityConfiguration.Config();
config.DependencyResolver = new UnityResolver(container);
// Maybe some formatters?
}
}
You also need a DependencyResolver:
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();
}
}
You can also take a look at this similiar question, except for the Owin-part. Unity.WebApi | Make sure that the controller has a parameterless public constructor
I had the same error and in my case the problem was, that i forgot to register a dependency that one of the classes, I had registered for dependency injection, injects in the constructor.
In your example, could it be that you inject something into MyEntities that you forgot to Register?
Install Nuget Package Unit.WebAP instead of Unity.MVC5
Make sure the correct unity package is installed using nuget
I Installed Unity.MVC5 and was facing similar exception "parameterless constructor"
public static void RegisterComponents()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
container.RegisterType<ICar, Tesla>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}

Using Unity IoC to register and resolve SignalR hubs

I think I'm missing something very simple and maybe just need a new set of eyes. I have an ASP.NET MVC application. In that app, I am using Unity for my IoC to handle dependency injection. Each of my repositories need to have a database factory injected into it and each database factory needs to have a principal injected into it. So far, I've been utilizing the PerRequestLifetimeManager to register these.
//Repositories
container.RegisterType<ChatMessageRepository>(new PerRequestLifetimeManager());
container.RegisterType<SignalRConnectionRepository>(new PerRequestLifetimeManager());
//Context
container.RegisterType<IPrincipal, Principal>(new PerRequestLifetimeManager());
container.RegisterType<IDatabaseFactory, DatabaseFactory>(new PerRequestLifetimeManager());
container.RegisterType<UnitOfWork>(new PerRequestLifetimeManager());
Logically, I've tried to register my Hub in the same fashion.
container.RegisterType<ChatHub>(new PerRequestLifetimeManager());
However, whenever I run my app and navigate away from my chat page, I get a "Resolution of the dependency failed" exception and the InnerException tells me "Operation is not valid due to the current state of the object." I've also tried using the default (Transient), PerResolve, and ContainerControlled lifetime Unity managers when registering these guys and cannot seem to get resolve my issue.
Could someone just provide me some demo code with how you used Unity in an ASP.NET MVC application to handle dependency injection into your signalr hubs?
Here's where Unity will inject parameters into my SignalR Hub
public class ChatHub : Hub
{
private readonly ChatMessageRepository _chatMessageRepository;
private readonly SignalRConnectionRepository _signalRConnectionRepository;
private readonly UnitOfWork _unitOfWork;
public ChatHub(ChatMessageRepository chatMessageRepository,
SignalRConnectionRepository signalRConnectionRepository,
UnitOfWork unitOfWork)
{
_chatMessageRepository = chatMessageRepository;
_signalRConnectionRepository = signalRConnectionRepository;
_unitOfWork = unitOfWork;
} ... }
Thanks!
Do it in 3 steps
First. Create UnityHubActivator class
public class UnityHubActivator : IHubActivator
{
private readonly IUnityContainer _container;
public UnityHubActivator(IUnityContainer container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
return (IHub)_container.Resolve(descriptor.HubType);
}
}
Second. Create Unity container and register your dependency resolver before run Startup class
unityContainer = new UnityContainer();
var unityHubActivator = new UnityHubActivator(_unityContainer);
GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => unityHubActivator);
//register some types in container
WebApp.Start<Startup>(startOptions);
Third. Use it in your Hub
public class MyHub : Hub
{
public MyHub(Logger logger)
{
logger.Info("hub constructor");
}
}
Note. I do not change anything in my Startup class
There's a trick to do that. You will need to do something like this:
container.RegisterType< ChatHub >(new InjectionFactory(CreateChatHub));
......
and then create a private method CreateChatHub
private static object CreateChatHub(IUnityContainer container)
{
return new ChatHub();
}
1 Create "UnitySignalRDependencyResolver.cs"
public class UnitySignalRDependencyResolver : DefaultDependencyResolver
{
protected IUnityContainer Container;
private bool IsDisposed = false;
public UnitySignalRDependencyResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
Container = container.CreateChildContainer();
}
/// <summary>
/// Gets the Autofac implementation of the dependency resolver.
/// </summary>
public static UnitySignalRDependencyResolver Current
{
get { return GlobalHost.DependencyResolver as UnitySignalRDependencyResolver; }
}
public override object GetService(Type serviceType)
{
if (Container.IsRegistered(serviceType))
{
return Container.Resolve(serviceType);
}
return base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
if (Container.IsRegistered(serviceType))
{
return Container.ResolveAll(serviceType);
}
return base.GetServices(serviceType);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (IsDisposed)
{
return;
}
if (disposing)
{
Container.Dispose();
}
IsDisposed = true;
}
}
2.Add your resolver to Owin pipeline
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Get container
IUnityContainer container = UnityConfig.Container;
// Create resolver
var resolver = new UnitySignalRDependencyResolver(container);
// Create SignalR Configuration
var config = new HubConfiguration
{
Resolver = resolver
};
// Start SignalR
app.Map("/signalr", map =>
{
map.RunSignalR(config);
});
}
}
3.Inject your dependency in your controller's constructor
public class ValuesController : ApiController
{
private readonly IMyDependency _myDependency;
public ValuesController(IMyDependency myDependency)
{
_myDependency= myDependency;
}
}

How to use dependency injection in ashx (Autofac, MVC4)

public class AutoCompleteCity : IHttpHandler
{
public IAutoCompleteRepository AutoCompleteRepository { get; set; }
public void ProcessRequest(HttpContext context)
{
}
}
public static void RegisterDependencies()
{
var builder = new ContainerBuilder();
builder.RegisterType<AutoCompleteRepository>().As<IAutoCompleteRepository>).SingleInstance();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
AutoCompleteRepository is registered with SingleInstance, but is always null when calling ProcessRequest.
How can I fix this?
Your code looks good. What I suspect is that you are missing in your PropertyInjectionModule httpModules setup in web.config. The following module setup is required for Autofac to work well with ASP.Net:
<add name="ContainerDisposal" type="Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web"/>
<add name="PropertyInjection" type="Autofac.Integration.Web.Forms.PropertyInjectionModule, Autofac.Integration.Web"/>
Note: the setup for ASP.Net WebForms integration is described here.
Try injecting your dependencies in constructor, if you want to do properties injection you should enable it with: PropertiesAutowired(), in general using autofac if you want to use property injection you need to enable it with PropertiesAutowired() configuration for class in which you want get the injected property, not in class which you want to inject.
prefered way:
public class AutoCompleteCity : IHttpHandler
{
public IAutoCompleteRepository AutoCompleteRepository { get; set; }
public AutoCompleteCity(IAutoCompleteRepository autoCompleteRepository) {
AutoCompleteRepository = autoCompleteRepository;
}
public void ProcessRequest(HttpContext context)
{
}
}
or try this:
public static void RegisterDependencies()
{
var builder = new ContainerBuilder();
builder.RegisterType<AutoCompleteRepository>().As<IAutoCompleteRepository>()
.SingleInstance();
builder.RegisterType<AutoCompleteCity>()
.As<IHttpHandler>()
.PropertiesAutowired(); //<--!!!
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
EDIT:
look here: https://groups.google.com/forum/#!topic/autofac/BkY4s4tusUc, to learn how to register IHttpHandler.
You can try this
public class AutoCompleteCity : IHttpHandler
{
private IAutoCompleteRepository _repo;
public IAutoCompleteRepository Repository
{
get
{
if (_repo==null)
{
_repo=AutofacDependencyResolver.Current.RequestLifetimeScope.Resolve<IAutoCompleteRepository>();
}
return _repo;
}
set
{
if (value!=null) _repo=value;
}
}
public void ProcessRequest(HttpContext context)
{
}
}

What is the correct way to register FluentValidation with Simple Injector?

I am able to register FluentValidation AbstractValidators using a FluentValidatorFactory. However, it doesn't feel right, because not all of the IoC container registrations happen during bootstrap / composition root. Instead, the fluent validators are registered by a separate factory:
The composition root:
public class SimpleDependencyInjector : IServiceProvider
{
public readonly Container Container;
public SimpleDependencyInjector()
{
Container = Bootstrap();
}
internal Container Bootstrap()
{
var container = new Container();
container.Register< // ...register all non-fluent-validator types, then
container.Verify();
return container;
}
public object GetService(Type serviceType)
{
return ((IServiceProvider)Container).GetService(serviceType);
}
}
An abstract fluent validator factory depending only on IServiceProvider
public abstract class FluentValidatorFactory : ValidatorFactoryBase
{
private IServiceProvider Injector { get; set; }
protected FluentValidatorFactory(IServiceProvider injector)
{
Injector = injector;
}
public override IValidator CreateInstance(Type validatorType)
{
return Injector.GetService(validatorType) as IValidator;
}
}
A fluent validator factory implementation for SimpleInjector
public class SimpleValidatorFactory : FluentValidatorFactory
{
public SimpleValidatorFactory(SimpleDependencyInjector injector)
: base(injector)
{
var validators = AssemblyScanner.FindValidatorsInAssembly(
Assembly.GetCallingAssembly());
validators.ForEach(validator =>
injector.Container.Register(
validator.InterfaceType, validator.ValidatorType));
injector.Container.Verify();
}
}
SimpleInjector has good support for open generics, and all of my fluent validator classes have signatures similar to the following:
public class SomeClassValidator : AbstractValidator<SomeClass>
{
public SomeClassValidator([depedencies injected here])
{
// ... set up validation rules
}
}
So, is there a better way to register the validators in the bootstrap / composition root, instead of using fluent's validator factory?
P.S. #DotNetJunkie -- would be great if you had a wiki page on this at simpleinjector.codeplex.com.
I think I figured this out myself.
1.) Register fluent's open generic IValidator<T> interface in the composition root:
public class SimpleDependencyInjector : IServiceProvider
{
public readonly Container Container;
public SimpleDependencyInjector()
{
Container = Bootstrap();
}
internal Container Bootstrap()
{
var container = new Container();
// some container registrations
var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
container.RegisterManyForOpenGeneric(typeof(IValidator<>), assemblies);
// some more registrations
container.Verify();
return container;
}
public object GetService(Type serviceType)
{
return ((IServiceProvider)Container).GetService(serviceType);
}
}
2.) Get rid of the SimpleValidatorFactory class.
3.) Make the FluentValidatorFactory a non-abstract, concrete class:
public class FluentValidatorFactory : ValidatorFactoryBase
{
private IServiceProvider Injector { get; set; }
public FluentValidatorFactory(IServiceProvider injector)
{
Injector = injector;
}
public override IValidator CreateInstance(Type validatorType)
{
return Injector.GetService(validatorType) as IValidator;
}
}
4.) Register the FluentValidatorFactory as the validation factory provider in global.asax:
var injector = new SimpleDependencyInjector();
FluentValidationModelValidatorProvider.Configure(
provider =>
{
provider.ValidatorFactory = new FluentValidatorFactory(injector);
}
);

Dependency Injection in Sharepoint 2010

I'm working on my first sharepoint project. Is there a way I can use dependency injection (like castle windsor) in sharepoint?
If so can you please provide a samle code.
Thanks
Use the SharePoint Service Locator from the MS Patterns & Practices group: http://spg.codeplex.com/
You can do like below. But this is not awesome because, SharepointClass is instantiated by sharepoint not by the dependency injection container. So for now, in SharepointClass you can resolve your dependency like Ioc.Resolve() and deeper dependencies of IService instance will be injected by Windsor.
public interface IMyCode
{
void Work();
}
public class MyCode : IMyCode
{
public void Work()
{
Console.WriteLine("working");
}
}
public interface IService
{
void DoWork();
}
public class MyService : IService
{
private readonly IMyCode _myCode;
public MyService(IMyCode myCode)
{
_myCode = myCode;
}
public void DoWork()
{
Console.WriteLine(GetType().Name + " doing work.");
_myCode.Work();
}
}
public class Ioc
{
private static readonly object Syncroot = new object();
private readonly IWindsorContainer _container;
private static Ioc _instance;
private Ioc()
{
_container = new WindsorContainer();
//register your dependencies here
_container.Register(Component.For<IMyCode>().ImplementedBy<MyCode>());
_container.Register(Component.For<IService>().ImplementedBy<MyService>());
}
public static Ioc Instance
{
get
{
if (_instance == null)
{
lock (Syncroot)
{
if (_instance == null)
{
_instance = new Ioc();
}
}
}
return _instance;
}
}
public static T Resolve<T>()
{
return Instance._container.Resolve<T>();
}
}
And in your sharepoint class
public class SharepointClass : SharepointWebpart //instantiated by sharepoint
{
public IService Service { get { return Ioc.Resolve<IService>(); } }
public void Operation()
{
Console.WriteLine("this is " + GetType().Name);
Service.DoWork();
}
}

Resources