How to debug when a dependency fails to instantiate? - c#

How do you debug dependency injection (using Unity DI) when the dependancy does not instantiate?
eg Given a service class with dependencies:
public class FooService : IFooService
{
[Dependency]
public BarService BarService { get; set; }
[Dependency]
public AnotherService AnotherService { get; set; }
// other code fails because BarService and AnotherService are null
}
And in Global.asax.cs
private void ConfigureIoC()
{
container
.ConfigureAutoRegistration()
.LoadAssembliesFrom(assemblyPaths)
.ExcludeSystemAssemblies()
.Include(If.Any, Then.Register())
.ApplyAutoRegistration();
var serviceLocator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
}
The IFooService is also instantiated by Unity, but that uses constructor injection instead (and it works):
public class FooController : Controller
{
private readonly IFooService _fooService;
public FooController(IFooService fooService)
{
_fooService = fooService;
}
}
How can I debug this to see why the dependencies are failing to instantiate. No exceptions are being thrown (or if they are then Elmah is not catching and logging them).

The dependency is not injected because the DependencyAttribute is on the concrete class instead of the interface.
As DI attributes can be harmful I would recommend you change the registration to
container.RegisterType<IFooService,FooService>(new InjectionProperty("BarService"), new InjectionProperty("AnotherService"));
Resolving IFooService will then return an instance of FooService with the injected dependencies.

Call container.Resolve<IFooService>();
Where/how is resolution of IFooService happening?

Related

Derived Class How to inject ?

ASP.Net Core Web API
Does the parent class have no empty constructor
derived class Autofac injection ?
If the injection class is added after the parameter, it cannot be used
public class A
{
public A(string e1,string e2){}
}
public class B:A
{
private readonly IProductService _productService;
public B(IProductService productService):base(string e1,string e2)
{
_productService = productService
}
public void test()
{
_productService.AddProduct("");
}
}
AutoFac has no problem configuring
_productService exception occurred
You should try it like this:
public B(IProductService productService, string e1,string e2):base(e1,e2)
{
_productService = productService
}
And then configure Autofac like this for this class registration:
builder.Register(c => new B(c.Resolve<IProductService>(), "e1_val","e2_val"));
If the B class will implement an interface at some point you can use it like this also:
builder.RegisterType<B>().As<IB>()
.WithParameter("e1", "e1value")
.WithParameter("e2", "e2value");
Keep in mind that you have a lot of flexibility with Autofac, please check their documentation at: Autofac Parameters Register for even more information.

Resolving dependencies dynamically using Autofac

Is it good to resolve the dependencies dynamically like the way i'm doing. Everywhere, it is suggested to use Constructor injection. I really don't understand the drawbacks of doing it the way i'm doing it. Code snippets as below..
Employee.cs
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public Department Department { get; set; }
}
IRepository.cs
public interface IRepository<TModel> where TModel : class
{
void Add();
IEnumerable<TModel> GetAll();
IEnumerable<TModel> GetByID();
}
Repository.cs
public class Repository<TModel> : IRepository<TModel> where TModel : class
{
public void Add()
{
throw new NotImplementedException();
}
public IEnumerable<TModel> GetAll()
{
throw new NotImplementedException();
}
public IEnumerable<TModel> GetByID()
{
throw new NotImplementedException();
}
}
EmployeeController.cs
public class HomeController : ApiController
{
IComponentContext _container;
public HomeController(IComponentContext container)
{
this._container = container;
}
public Repository<TModel> Using<TModel>() where TModel :class
{
var repository = _container.Resolve(typeof(IRepository<TModel>));
return repository as Repository<TModel>;
}
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return Using<Employee>().GetAll();
}
}
Global.asax
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
var container = builder.Build(Autofac.Builder.ContainerBuildOptions.None);
var webApiResolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = webApiResolver;
}
Say i've 5 repositories, Constructor injection will resolve all the 5 dependencies for a request i make. I might not use 5 repositories for each and every request. SO i thought of resolving dependencies dynamically by passing the type like i'm doing it in Using<TModel>(). Any suggestions would be appreciated..!! Thank you...!!
Refrain from using the container directly inside your application components; this leads to all kinds of troubles such as maintainability and testability issues. Directly resolving instances from within application code is a well-known anti-pattern known as Service Locator.
As a first refactoring, you can instead apply the Unit of Work pattern. A Unit of Work allows access to underlying repositories. For instance:
public interface IUnitOfWork
{
IRepository<TModel> Repository<TModel>();
}
public sealed class HomeController : ApiController
{
private readonly IUnitOfWork _unitOfWork;
public HomeController(IUnitOfWork unitOfWork)
{
this._unitOfWork = unitOfWork;
}
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return this._unitOfWork.Repository<Employee>().GetAll();
}
}
Within the Composition Root (where it is allowed to access the container), we can now create an IUnitOfWork implementation that resolves repositories dynamically:
private sealed class AutofacUnitOfWork : IUnitOfWork
{
private readonly IComponentContext _container;
public AutofacUnitOfWork(IComponentContext container)
{
this._container = container;
}
public IRepository<TModel> Repository<TModel>()
{
return _container.Resolve<IRepository<TModel>>();
}
}
This pattern simplifies your application components considerably and prevents downsides that the Service Locator anti-pattern typically causes.
Although applying the Unit of Work pattern might be a useful step into the right direction, an even better approach is to skip the Unit of Work directly and simply inject a required repository directly into application components:
public sealed class HomeController : ApiController
{
private readonly IRepository<Employee> _employeeRepository;
public HomeController(IRepository<Employee> employeeRepository)
{
this._employeeRepository = employeeRepository;
}
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return this._employeeRepository.GetAll();
}
}
Say i've 5 repositories, Constructor injection will resolve all the 5 dependencies for a request i make. I might not use 5 repositories for each and every request.
Note that from a performance perspective, you should typically not be concerned whether dependencies are used or not. Autofac is in most cases fast enough and it is unlikely that this will actually cause any performance problems in your production systems.
From a design perspective however you should be more worried if a class has many dependencies, while methods just use a few of them. This means that the methods in the class have little cohesion. This is an indication that the class should be split up into multiple smaller classes; it has multiple responsibilities.

ASP.Net MVC using IoC Windsor Castle - components are waiting for dependencies

Description of my Windsor resolving problem
I got MVC web.api project.
I use Windsor Castle for IoC. But at this moment I have a problem with resolving already registred components.
Specifically, I get this error during I am checking for potentially misconfigured components:
Some dependencies of this component could not be statically resolved.
'FoodRate.Web.DataServices.PlaceDataService' is waiting for the following dependencies:
- Service 'FoodRate.Web.DataServices.PlaceMapper' which was registered but is also waiting for dependencies.
'FoodRate.Web.DataServices.PlaceMapper' is waiting for the following dependencies:
- Service 'FoodRate.Web.DataServices.PlaceTypeMapper' which was registered but is also waiting for dependencies.
Some dependencies of this component could not be statically resolved.
'FoodRate.Web.DataServices.PlaceMapper' is waiting for the following dependencies:
- Service 'FoodRate.Web.DataServices.PlaceTypeMapper' which was registered but is also waiting for dependencies.
I understand why DataService named PlaceDataService has to wait for its dependencies. But I do not understand why there is a problem with PlaceMapper and its dependency PlaceTypeMapper.
I checked the status of the PlaceTypeMapper resolving inside the container) and PlaceTypeMapper can be resloved without errors.
And as shown on the scren above the PlaceTypeMapper does not have any dependency. And status is really:
All requierd dependencies can be resolved.
Class definitions
I have attached my classes definitions:
public interface IMapper
{
}
PlaceMapper class definition:
public interface IPlaceMapper : IMapper
{
/* ... some public definitions */
}
public class PlaceMapper : IPlaceMapper
{
private readonly IPlaceTypeMapper placeTypeMapper;
private readonly IGeoLocationMapper geoLocationMapper;
public PlaceMapper(IGeoLocationMapper geoLocationMapper, IPlaceTypeMapper placeTypeMapper)
{
this.geoLocationMapper = geoLocationMapper;
this.placeTypeMapper = placeTypeMapper;
}
/* .... Some public methods */
}
PlaceTypeMapper definition:
public interface IPlaceTypeMapper : IMapper
{
/* ... Some public definitions */
}
public class PlaceTypeMapper : IPlaceTypeMapper
{
public PlaceTypeDto ConvertPlaceTypeToPlaceTypeDto(PlaceType placeType)
{
/* .... */
}
public IList<PlaceTypeDto> ConvertPlaceTypeToPlaceTypeDto(IList<PlaceType> placeTypes)
{
/* .... */
}
}
DataService definition:
public interface IDataService
{
}
public class PlaceDataService : IPlaceDataService
{
private readonly IUnitOfWork unitOfWork;
private readonly IPlaceMapper placeMapper;
private readonly IGeoLocationMapper geoLocationMapper;
public PlaceDataService(IUnitOfWork unitOfWork, IPlaceMapper placeMapper, IGeoLocationMapper geoLocationMapper)
{
this.unitOfWork = unitOfWork;
this.placeMapper = placeMapper;
this.geoLocationMapper = geoLocationMapper;
}
public PlaceDto GetPlace(int id)
{
/* ... */
}
public IList<PlaceDto> GetPlaceByLocation(GeoLocationDto geoLocation)
{
/* ... */
}
}
And Windsor installer section (inter alia):
container.Register(Component.For<IUnitOfWork>().
ImplementedBy<UnitOfWork>().
LifestyleTransient());
container.Register(Classes.FromThisAssembly().
BasedOn<IMapper>().
WithService.AllInterfaces().
LifestyleSingleton());
container.Register(Classes.FromThisAssembly().
BasedOn<IDataService>().
WithService.AllInterfaces().
LifestyleTransient());
I will be grateful for any recommendations..

MVC 4 Autofac and Generic Repository pattern

I am utilizing the Unit Of Work and Generic Repository pattern in my MVC 4 app. The problem I am trying to solve is creating Repository stubs for every entity in my system. In order to utilize the Autofac Ioc I am having to create a repository class and interface for every entity so that I can register it in Autofac.
app start...
builder.RegisterType<SchoolDetailRepository>().As<ISchoolDetailRepository>().InstancePerHttpRequest();
Repository class
public class SchoolDetailRepository : RepositoryBase<SchoolDetail>, ISchoolDetailRepository
{
public SchoolDetailRepository(IDatabaseFactory databaseFactory) : base(databaseFactory)
{
}
}
Interface
public interface ISchoolDetailRepository : IRepository<SchoolDetail>
{
}
It seems like a lot of extra work.
Is there a way to register the generic repository of Type rather than creating all these empty classes?
Then in my service class I can just have the generic type passed into the constructor via Ioc like...
public class SchoolService : ISchoolService
{
private readonly IRepository<SchoolDetail> _schoolRepository;
private readonly IUnitOfWork _unitOfWork;
public SchoolService(IRepository<SchoolDetail> schoolRepository, IUnitOfWork unitOfWork)
{
this._schoolRepository = schoolRepository;
this._unitOfWork = unitOfWork;
}
}
Container config
// Autofac iOC
var builder = new ContainerBuilder();
// register controllers
builder.RegisterControllers(Assembly.GetExecutingAssembly());
// register services
builder.RegisterType<MembershipService>().As<IMembershipService>().InstancePerHttpRequest();
builder.RegisterType<SchoolService>().As<ISchoolService>().InstancePerHttpRequest();
builder.RegisterType<StudentService>().As<IStudentService>().InstancePerHttpRequest();
builder.RegisterType<ClassRoomService>().As<IClassRoomService>().InstancePerHttpRequest();
builder.RegisterType<CourseService>().As<ICourseService>().InstancePerHttpRequest();
builder.RegisterType<SchoolYearService>().As<ISchoolYearService>().InstancePerHttpRequest();
builder.RegisterType<EnrollmentService>().As<IEnrollmentService>().InstancePerHttpRequest();
builder.RegisterType<TeacherService>().As<ITeacherService>().InstancePerHttpRequest();
// register data infrastructure
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();
builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerHttpRequest();
// register repositories
builder.RegisterType<SchoolRepository>().As<ISchoolRepository>().InstancePerHttpRequest();
builder.RegisterType<TeacherRepository>().As<ITeacherRepository>().InstancePerHttpRequest();
builder.RegisterType<MembershipRepository>().As<IMembershipRepository>().InstancePerHttpRequest();
builder.RegisterType<RoleRepository>().As<IRoleRepository>().InstancePerHttpRequest();
builder.RegisterType<ProfileRepository>().As<IProfileRepository>().InstancePerHttpRequest();
builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerHttpRequest();
builder.RegisterType<StudentRepository>().As<IStudentRepository>().InstancePerHttpRequest();
builder.RegisterType<ClassRoomRepository>().As<IClassRoomRepository>().InstancePerHttpRequest();
builder.RegisterType<CourseRepository>().As<ICourseRepository>().InstancePerHttpRequest();
builder.RegisterType<EnrollmentRepository>().As<IEnrollmentRepository>().InstancePerHttpRequest();
builder.RegisterType<SchoolYearRepository>().As<ISchoolYearRepository>().InstancePerHttpRequest();
builder.RegisterType<GradeLevelRepository>().As<IGradeLevelRepository>().InstancePerHttpRequest();
//builder.RegisterType<SchoolDetailRepository>().As<ISchoolDetailRepository>().InstancePerHttpRequest();
builder.RegisterGeneric(typeof(RepositoryBase<SchoolDetail>)).As(typeof(IRepository<SchoolDetail>));
// build and setup resolver
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
the exception is coming from the above code where the expression you gave me runs..
builder.RegisterGeneric(typeof(RepositoryBase<SchoolDetail>)).As(typeof(IRepository<SchoolDetail>));
RepositoryBase
public abstract class RepositoryBase<T> where T : class
{
private LearningCompactPilotContext _dataContext;
private readonly IDbSet<T> _dbset;
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
_dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get; private set;
}
protected LearningCompactPilotContext DataContext
{
get { return _dataContext ?? (_dataContext = DatabaseFactory.Get()); }
}
... more code
}
You need the open generics feature of Autofac:
builder.RegisterGeneric(typeof(RepositoryBase<>))
.As(typeof(IRepository<>));
Then you use your repositories exactly as you described:
public class SomeService
{
private readonly IRepository<SomeEntity> _repository;
public SchoolService(IRepository<SomeEntity> repository)
{
this._repository= repository;
}
}

can castle resolve cross dependent properties?

i have a situation silmilar as following
public class FooService : IFooService
{
public IBarService BarService { get; set; }
}
public class BarService : IBarService
{
public IFooService FooService { get; set; }
}
IFooService and IBarService both are inherited from IApplicationService
Component registrar looks like this
container.Register(
AllTypes.FromAssemblyContaining<IApplicationService>()
.BasedOn<IApplicationService>()
.WithService.FromInterface()
.LifestyleSingleton());
The problem is that properties are null. If i add any other service that doesnt use foo or bar service, the service is resolved correctlty.
It looks like castle windsor cant handle cross references. Or is there something i should add into component registrar?
I tried constructor injection and seems it is working.

Categories