How to use dependency injection in ashx (Autofac, MVC4) - asp.net-mvc

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)
{
}
}

Related

Configuring Autofac with ASP.NET MVC 5

I am trying to implement Dependency Injection with Autofac in an ASP.NET MVC5 Project. But I am getting the following error every time:
None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyProjectName.DAL.Repository` ........
My Autofac configuration code in App_Start folder as follows:
public static class IocConfigurator
{
public static void ConfigureDependencyInjection()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<Repository<Student>>().As<IRepository<Student>>();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
In Global.asax file:
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
// Other MVC setup
IocConfigurator.ConfigureDependencyInjection();
}
}
Here is my IRepository:
public interface IRepository<TEntity> where TEntity: class
{
IQueryable<TEntity> GelAllEntities();
TEntity GetById(object id);
void InsertEntity(TEntity entity);
void UpdateEntity(TEntity entity);
void DeleteEntity(object id);
void Save();
void Dispose();
}
Here is my Repository:
public class Repository<TEntity> : IRepository<TEntity>, IDisposable where TEntity : class
{
internal SchoolContext context;
internal DbSet<TEntity> dbSet;
public Repository(SchoolContext dbContext)
{
context = dbContext;
dbSet = context.Set<TEntity>();
}
.....................
}
Here is my Student Controller:
public class StudentController : Controller
{
private readonly IRepository<Student> _studentRepository;
public StudentController()
{
}
public StudentController(IRepository<Student> studentRepository)
{
this._studentRepository = studentRepository;
}
....................
}
What's wrong in my Autofac Configuration..Any Help Please??
To inject a dependency you need to have satisfied all of the dependencies for all of the pieces down the chain.
In your case, the Repository constructor cannot be satisfied without a SchoolContext.
So in your registration add:
builder.RegisterType<SchoolContext>().InstancePerRequest();
See http://docs.autofac.org/en/latest/lifetime/instance-scope.html#instance-per-request

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

how to implement dependency injection in mvc?

I'm trying to implement dependency injection but i know how to implement the interface and repository of classes then i don't know what shall i do.
This my sample:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
}
This is my interface:
public interface IUser
{
IEnumerable<User> GetUsers();
void AddUser(User user);
void EditUser(User user);
void DeleteUser(int id);
User UserGetById(int id);
void Save();
}
This is my repository:
public class UserRepsitory:IUser
{
private _Context _context;
public UserRepsitory(_Context _context)
{
this._context = _context;
}
public IEnumerable<User> GetUsers()
{
return _context.User.ToList();
}
public void AddUser(User user)
{
_context.User.Add(user);
}
public void EditUser(User user)
{
_context.Entry(user).State = System.Data.Entity.EntityState.Modified;
}
public User UserGetById(int id)
{
return _context.User.Find(id);
}
public void Save()
{
_context.SaveChanges();
}
public void DeleteUser(int id)
{
var Search = _context.User.Find(id);
_context.User.Remove(Search);
}
}
And one of method in controller:
private IUser userRepsitory;
public UsersController()
{
this.userRepsitory = new UserRepsitory(new _Context());
}
public UsersController(IUser UserRepository)
{
this.userRepsitory = UserRepository;
}
public ActionResult Index()
{
return View(userRepsitory.GetUsers());
}
What is the next step?
The first thing is, get rid of the default constructor where we are hard coding the initialization of UserRepository ! We will do that in the dependency injection way.
public UsersController : Controller
{
private readonly IUser userRepsitory;
public UsersController(IUser UserRepository)
{
this.userRepsitory = UserRepository;
}
public ActionResult Index()
{
return View(userRepsitory.GetUsers());
}
}
Now we need something to tell the MVC framework which version/implementation of IUser should be used when the code runs. you can use any dependency injection frameworks to do that. For example, If you are in MVC 6, you can use the inbuilt dependency injection framework to do that. So go to your Startup class and in your ConfigureServices method, you can map an interface to a concrete implementation.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IUser, UserRepository>();
}
}
If you are in a previous version of MVC, you may consider using any of the dependency injection frameworks available like Unity, Ninject etc.
It is pretty much same, you map an interface to a concrete implementation
Ninject
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUser>().To<UserRepository>();
}
You do not need to put the mapping in a cs file. You can define that in a config file. For example, when you use Unity you can do something like this in your config file (web config or an external config file for unity configuration)
Unity
<alias alias="IUser" type="YourNamespace.IUser, YourAssemblyName" />
<register type="IUser" mapTo="YourNamespace.UseRepository, YourAssemblyName">
In order to create and configure your project with Spring DI(Dependency Feature) you must configure beans.
Create an xml file (if its not there) and add references to bean
In this xml file, provide references to the classes you want to inject. Example:
<bean id="Name of the JAVA Class" class="the Full path of the JAVA class"/>
And in your class where you are supposed to call the referencing class(above), calling procedure would be like :
#Controller
public class MyController {
private full.path.of.my.class.named.MyJavaClass _class;
#Autowired
private MyController (full.path.of.my.class.MyJavaClass class)
{
this._class= class;
}
}
Now say if you a function in MyJavaClass
public int sum(int x, int y){
return x+y;
}
Then without creating object of MyJavaClass you can inject like the following in your controller:
_class.Sum(10,15);
YOU DO NOT CREATE AN INSTANCE OF THIS CLASS.

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

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

Resources