First of all, let me provide some sample code:
public abstract class BaseEntity { }
public class MyEntity : BaseEntity { }
public class MyCustomEntity : BaseEntity { }
public interface IStore<TEntity> where TEntity : BaseEntity { }
public class BaseStore<TEntity> : IStore<TEntity> where TEntity : BaseEntity { }
public class MyCustomEntityStore : BaseStore<MyEntity> { }
So basically I have an abstract entity and two derived types. I created a repository class which is hiding all the basic stuff around the BaseEntity (for example fill the "LastModifiedBy" property). But for some cases, I need specific behaviour to saving an entity, so I need to derive from the BaseStore, and implement the custom behaviour in MyCustomEntityStore. So far, it is easy.
The problem is i would like to use Autofac to resolve dependencies in my application. My goal would be to do this:
public class SomeClass {
private readonly IStore<MyEntity> MyEntityStore;
private readonly IStore<MyCustomEntity> MyCustomEntityStore;
public SomeClass(IStore<MyEntity> mes, IStore<MyCustomEntity> mces)
{
MyEntityStore = mes;
MyCustomEntityStore = mces;
}
}
I would like to inject an instance of BaseStore<MyEntity> to IStore<MyEntity> and MyCustomEntityStore to IStore<MyCustomEntity>. This is working fine with the MyCustomEntityStore (which has a concrete implementation derived from the base store), but i do not want to create empty classes just to inherit the BaseStore<MyEntity>. I registered my components like this:
builder.RegisterAssemblyTypes(Assembly.Load("Project.Data")).Where(t => t.Name.EndsWith("Store")).AsImplementedInterfaces().InstancePerRequest();
Although these instances can be in the place of these interfaces, Autofac can not resolve the IStore<MyEntity>.
Thanks for all the help!
I managed to solve the problem with this registering:
builder.RegisterGeneric(typeof(BaseStore<>))
.As(typeof(IStore<>))
.InstancePerRequest();
builder.RegisterAssemblyTypes(Assembly.Load("Project.Data"))
.Where(t => t.Name.EndsWith("Store"))
.AsImplementedInterfaces()
.InstancePerRequest();
Can anyone confirm, this is the right way?
Related
I've read a lot of questions of people asking how to have implicit ctor inheritance, so to not have to copy them around.
This question is totally the opposite: why C# is not forcing me to do it anymore? I want the derived classes to be forced to implement the base constructors...but it's not happening. What am I doing wrong?
Base class
public abstract class LogicalDevice
{
private LogicalDevice()
{
}
protected LogicalDevice(string id)
{
}
}
Intermediate derived class
public abstract class Device : LogicalDevice
{
public Device(string ID)
: base("ID")
{
}
public Device(ConfigurationData configuration)
: base(configuration["ID"])
{
}
}
Final derived class
internal class CoffeMachineDevice : Device
{
public CoffeMachineDevice (ConfigurationData configuration)
: base(configuration)
{
}
}
Why the class CoffeMachineDevice compiles?
C# requires that every constructor in derived class must call a constructor in the base class. But there is no requirement that is must call each constructor of the base class.
That's why CoffeMachineDevice compiles.
I have the following code:
public abstract class ApiBaseController : ApiController
{
protected IUow Uow { get; set; }
}
and:
public class ContentStatusController : ApiBaseController
{
public ContentStatusController(IUow uow)
{
Uow = uow;
}
}
Is there any reason why I could not code the assignment of Uow (using IOC) in the ApiBaseController?
The reason I ask is because I am trying to do something similar to the Code Camper application sample and I notice that in that sample the Unit of work is assignment is always performed in the constuctors of the controllers themselves rather than in the ApiBaseConstructor. In the examples I see this is the only thing that's done in the constructors.
If I did the assignement in the base controller then how could I code that and would Uow still need to have "protected" for it to be available in controllers that inherit from the ApiBaseController?
Your IOC container is injecting dependencies via constructors. If you want to continue to use that mechanism (some containers allow e.g. property injection, but not everyone likes to do that) then you'll still need to have the same constructor in your derived class to pass the injected component down to the base class1.
Something like:
public abstract class ApiBaseController : ApiController
{
public ApiBaseController(IUow uow)
{
Uow = uow;
}
protected IUow Uow { get; private set; }
}
public class ContentStatusController : ApiBaseController
{
public ContentStatusController(IUow uow) : base(uow) //<-- This is needed
{
}
}
1Because classes don't inherit constructors.
I have a base repository contract which other contracts extend, like follows
public interface IBaseRepository<T> where T : class
{
IList<T> GetContents();
}
and then there are other contracts which extend it like follows
public interface IRepository1 : IBaseRepository<MyClass1>
{
}
public interface IRepository2 : IBaseRepository<MyClass2>
{
}
I implement IRepository1 as follows
public class Repository1 : IRepository1
{
public IList<MyClass1> GetContents()
{
//some code goes here
}
}
similarly for IRepository2
public class Repository2 : IRepository2
{
public IList<MyClass2> GetContents()
{
//some code goes here
}
}
Now i have a service Service1 which implments IService like follows
public class Service1 : IService
{
}
I want to use my base repository (IBaseRepository) here in my service constructor, get an instance of this base repository and use it like so
public class Service1 : IService
{
private IBaseRepository<T> _baseRepository;
public Service1(IBaseRepository<T> baseRepository)
{
_baseRepository = baseRepository;
}
public MyMethod1()
{
var contentsOfType1 = _baseRepository<MyClass1>.GetContents();
}
public MyMethod1()
{
var contentsOfType2 = _baseRepository<MyClass2>.GetContents();
}
}
and this is what i am unable to do.
So i have a generic base repository contract with type T and have other contracts (interfaces) extending the base contract and also specifying what type T will be.
All these contracts (which extend generic base contract) have thier individual implementations.
What i want to do is in my service class, instantiate this generic base contract, and use it to infer the extending types (and hence implementations) and use the method from the base repository.
So if the base contract is
IBaseRepository<T>
and extending contract is
IRepository1 : IBaseRepository<MyClass1>
which is implemented by
Repository1 : IRepository1
i want to use this in my service class like
public class service()
{
*private IBaseRepository<T> _repo;
public service(IBaseRepository<T> repo)
{
*_repo = repo;
}
public void MyMethod()
{
*var x = _repo<MyClass1>.MethodFromIBaseRepository()
}
}
So its the *marked lines i want to achieve, which i am unable to.
I am using castle windsor for DI.
Thanks for your help guys
You should not have other repository interfaces besides your generic IRepository<T>. If you need those, you are missing an abstraction.
For instance, a common reason for people to have custom repository interfaces is because they have a custom query that some repository has, while other don't. For instance:
public interface IEmployeeRepository : IRepository<Employee>
{
Employee GetEmployeeOfTheMonth(int month);
}
The problem here is that the IEmployeeRepository is abused for a 'custom query'. Custom queries deserve their own (generic) abstraction:
// Defines a query
public interface IQuery<TResult>
{
}
// Defines the handler that will execute queries
public interface IQueryHandler<TQuery, TResult>
where TQuery : IQuery<TResult>
{
TResult Handle(TQuery query);
}
With this abstraction we can add custom queries to the system, without the need of creating IRepository<T> derivatives:
public class GetEmployeeOfTheMonthQuery : IQuery<Employee>
{
[Range(1, 12)]
public int Month { get; set; }
}
class GetEmployeeOfTheMonthHandler : IQueryHandler<GetEmployeeOfTheMonthQuery, Employee>
{
public Employee Handle(GetEmployeeOfTheMonthQuery query)
{
// todo: query the database, web service, disk, what ever.
}
}
A consumer that needs to know the employee of the month, can now simply take a dependency on IQueryHandler<GetEmployeeOfTheMonthQuery, Employee> and execute the query as follows:
var query = new GetEmployeeOfTheMonthQuery { Month = 11 };
var employee = this.employeeOfMonthHandler.Handle(query);
This might seem like overhead, but this model is very flexible, scalable, and has many interesting benefits. For instance, it is very easy to add cross-cutting concerns by wrapping handlers with decorators.
This also allows our reposities to be hidden behind one generic interface, which allows us to easily batch register them at once and add decorators to them as well.
For more in depth information, read this article: Meanwhile… on the query side of my architecture.
Not possible. The inversion of control container provide dependencies through the constructor, hence it must know in the constructor what type you want to get. So you should do this:
public class service()
{
private IBaseRepository<MyClass1> _repo;
public service(IBaseRepository<MyClass1> repo)
{
_repo = repo;
}
public void MyMethod()
{
var x = _repo.MethodFromIBaseRepository()
}
}
I'm looking for a possible solution to the following.
I have a base class that has a dependency which I currently use property injection to satisfy.
public class BaseClass {
IService SomeService { get; set; }
}
I have multiple classes which inherit from this base class.
public class DerivedClass : BaseClass, IDerivedClass {
}
And I inject using the following.
builder.RegisterType<DerivedClass>().As<IDerivedClass>().OnActivated(e => e.Instance.SomeService = e.Context.Resolve<IService>());
I do this for about 12 other classes which extend the base class. Is there a way so that any class extending BaseClass will get my IService registration without setting up an Activation event for each registration? It's working fine like this, but would just like to clean up the registrations.
Just use constructor injection. Create constructor with parameters for your class like
public DerivedClass(IServiceOne service1, IService2 service2)
{
this._service1 = service1;
this._service2 = service2;
}
and make autofac doing his job automatically, like
builder.RegisterType<T>();
I'm using Ninject DI container. And I've got the two
public interface IRepository<T> where T : AbstractEntity<T>, IAggregateRoot
{
// methods signatures
}
public class Repository<T> : IRepository<T> where T : AbstractEntity<T>, IAggregateRoot
{
// implementations
}
Then I'm trying to bind them in a separate module
public class DataAccessModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
this.Bind<IRepository<>>().To<Repository<>>();
}
}
where this.Bind<IRepository<>>().To<Repository<>>(); is not recognized as a statement.
How do I make a bind?
Snagged this piece from here. Looks like it worked for them:
Bind(typeof(IRepository<>)).To(typeof(Repository<>));