How to Register a conventional Interface in Autofac - autofac

I have an autofac DI in my project.
I want to expose an interface by conventional which all other interfaces of my project will inherit from. Is it possible to automatically register the components of the inherited interfaces at start up level? For example:
Public interface IConvetionInterface {}
public interface IImplementationA:IConvetionInterface
{
public void DoSomethingA();
}
public interface IImplementationB:IConvetionInterface
{
public void DoSomethingB();
}
Injecting through constructor;
public class ConsumerA
{
private readonly IImplementationA _a;
public DealerRepository(IImplementationA A)
{
_a= A;
}
public Act()
{
_a.DoSomethingA();
}
}
How do I register IConvetionInterface to make all its dependencies resolve in Autofac.

I have been able to come up with this solution by using autofac Assembly Scanning Configuration as provided in their documentation page Autofac Documentation Page
I have an open generic interface
public interface IRepository<TEntity, TPrimaryKey> where TEntity : class, IEntity<TPrimaryKey>
{ }
Implemented by
public class Repository<TEntity, TPrimaryKey> : RepositoryBase<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>{}
Then, I created an empty interface
public interface IConventionDependency
{
}
This method was called to register my components at startup level:
public static void RegisterAPSComponents(ContainerBuilder builder)
{
builder.RegisterType<APSContext>().InstancePerRequest();
builder.RegisterGeneric(typeof(Repository<,>)).As(typeof(IRepository<,>)).InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(typeof(IConventionDependency).Assembly).AssignableTo<IConventionDependency>().As<IConventionDependency>().AsImplementedInterfaces().AsSelf().InstancePerLifetimeScope();
}
By the above registration, any interface that inherits from IConventionDependency will be registered automatically in the container.
example:
create an interface:
public interface IDealerRepository : IConventionDependency
{
List<Dealers> GetDealers();
}
then Implement the interface :
public class DealerRepository : IDealerRepository
{
private readonly IRepository<VTBDealer, int> _repository;
public DealerRepository(IRepository<VTBDealer, int> repository)
{
_repository = repository;
}
public List<Dealers> GetDealers()
{
return _repository.GetAllList().MapTo<List<Dealers>>();
}
}
in conclusion, without explicitly registering IDealerRepository, it gets resolved in MVC Controller constructor.

Related

Why Dependency Injection doesn't know about my repo?

I have a weird situation. I need to use Entity Framework 6.2 for my .net core app.
An ordinary Controller
public class SampleApiController : BaseController
{
// use _repo and other stuff
}
Base Controller
public class BaseController : Controller
{
protected IRepo_repository;
public BaseController(IRepo repository)
{
_repository = repository;
}
public BaseController() : this(null)
{
}
}
App DBContext
public class SampleContext : DbContext
{
public SampleContext(string connectionString)
:base(connectionString)
{
try
{
this.Database.Log = (s) => System.Diagnostics.Debug.Write(s);
}
catch (Exception e)
{
//CurrentLogger.Log.Error(e);
}
}
public DbSet<Test1> Test1s { get; set; }
public DbSet<Test2> Test2s { get; set; }
}
Repository interface
public interface IRepo
{
// methods definition
}
Repository class
public interface Repo : IRepo
{
// methods implementation
}
Startup.cs -> ConfigureServices method
services.AddScoped<SampleContext>((s) => new SampleContext(configuration["ConnectionStrings:SampleApp"]));
services.AddScoped<IRepo, Repo>();
In this picture you could see that repository param is empty... not initialized with Repo instance... (!!! In this picture IRepo is IRepositoryBase)
Solution !
As CodeNotFound and Riscie said in comments, the problem was that BaseController was initialized with null... Thanks guys!
Try this:
Repository interface
public interface IRepo
{
// methods definition
}
Repository class
I have changed this from interface to class and made it implement the IRepo Interface
public class Repo : IRepo
{
// methods implementation
}
Edit: Also remove the second constructor
public class BaseController : Controller
{
protected IRepo_repository;
public BaseController(IRepo repository)
{
_repository = repository;
}
//second constructor most likely introduces the problem
}
You normally pass IRepo from SampleApiController to BaseController.
Base on my understanding, you do not need no argument constructor in BaseController. If so, you might want to remove it to prevent _repository being null.
public class SampleApiController : BaseController
{
public SampleApiController(IRepo repository)
: base(repository)
{
}
}
public class BaseController : Controller
{
protected IRepo _repository;
public BaseController(IRepo repository)
{
_repository = repository;
}
/*public BaseController() : this(null)
{
}*/
}
public interface IRepo
{
// methods definition
}

Multiple registration configuration based on string info Autofac

Finally I found the answer, thanks #yeah-buddy
Autofac Resolve constructor instance from Container?
public class Car
{
public Car(IEngine engine) { }
}
public interface IEngine { }
public interface IRepository { }
public class Engine : IEngine
{
public Engine(IRepository repository) { }
}
public class GenericRepository : IRepository
{
public GenericRepository(string carName) { } // !!! Generic Repository write information to carName table, this dependency is keypoint)
}
I want to register:
"Ferrari": Use Engine with GenericRepository("Ferrari")
"Volvo": Use Engine with GenericRepository("Volvo")
I want to resolve:
Get "Ferrari" Car
Get "Ferrari" Repository
How can I achieve this requirement by Autofac?

MvvmCross: IoC with Decorator pattern, two implementations of the same interface

I'd like to implement the Decorator pattern in one of my Mvx projects. That is, I'd like to have two implementations of the same interface: one implementation that is available to all of the calling code, and another implementation that is injected into the first implementation.
public interface IExample
{
void DoStuff();
}
public class DecoratorImplementation : IExample
{
private IExample _innerExample;
public Implementation1(IExample innerExample)
{
_innerExample = innerExample;
}
public void DoStuff()
{
// Do other stuff...
_innerExample.DoStuff();
}
}
public class RegularImplementation : IExample
{
public void DoStuff()
{
// Do some stuff...
}
}
Is it possible to wire up the MvvmCross IoC container to register IExample with a DecoratorImplementation containing a RegularImplementation?
It depends.
If DecoratorImplementation is a Singleton, then you could do something like:
Mvx.RegisterSingleton<IExample>(new DecoratorImplementation(new RegularImplementation()));
Then calls to Mvx.Resolve<IExample>() will return the instance of DecoratorImplementation.
However, if you need a new instance, unfortunately the MvvmCross IoC Container doesn't support that. It would be nice if you could do something like:
Mvx.RegisterType<IExample>(() => new DecoratorImplementation(new RegularImplementation()));
Where you'd pass in a lambda expression to create a new instance, similar to StructureMap's ConstructedBy.
Anyway, you may need to create a Factory class to return an instance.
public interface IExampleFactory
{
IExample CreateExample();
}
public class ExampleFactory : IExampleFactory
{
public IExample CreateExample()
{
return new DecoratorImplementation(new RegularImplementation());
}
}
Mvx.RegisterSingleton<IExampleFactory>(new ExampleFactory());
public class SomeClass
{
private IExample _example;
public SomeClass(IExampleFactory factory)
{
_example = factory.CreateExample();
}
}

Entity Framework using Repository Pattern, Unit of Work and Unity

Using a combination provided from this example and this implementation I am trying to create a solution that decouples the UnitOfWork class from the individual repositories, as they violate the Open-Closed Principle, since every time you added a new repository you would have to modify the UnitOfWork class. I am using Unity as the IoC container to wire up dependencies.
The problem I have is that in automatically wiring up the UnitOfWork, IDbContext and the repositories (IEmployeeRepository and ICustomerRepository) using Unity, the repositories will be injected with separate instances of the UnitOfWork, which, of course, defeats the purpose. I need to share the context across the repositories, and it seems I am missing a piece to this puzzle - at the moment (see Service layer) the UnitOfWork instantiated will be different to the UnitOfWork for each of repositories.
How do inject the IUnitOfWork into the service layer and pass this instantiated shared UnitOfWork class to the respective repositories, using Unity and dependency injection?
Here's my proposed (fabricated) solution:
Repositories
public interface IRepository<TEntity> where TEntity : class
{
TEntity Create();
// omitted for brevity
}
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : class
{
private readonly DbContext _context;
public Repository(IUnitOfWork uow)
{
_context = uow.Context;
}
public virtual TEntity Create(TEntity entity)
{
return _context.Set<TEntity>().Add(entity);
}
// omitted for brevity
}
public interface IEmployeeRepository : IRepository<Employee>
{
}
public interface ICustomerRepository : IRepository<Customer>
{
}
public class EmployeeRepository : Repository<Employee>
{
public EmployeeRepository(IUnitOfWork uow)
: base(uow)
{
}
}
public class CustomerRepository : Repository<Customer>
{
public CustomerRepository(IUnitOfWork uow)
: base(uow)
{
}
}
DbContext Factory
public interface IDbContextFactory
{
DbContext GetContext();
}
public class DbContextFactory : IDbContextFactory
{
private readonly DbContext _context;
public DbContextFactory()
{
_context = new MyDbContext("ConnectionStringName");
}
public DbContext GetContext()
{
return _context;
}
}
Unit Of Work
public interface IUnitOfWork
{
void SaveChanges();
DbContext Context { get; }
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly DbContext _context;
private bool disposed = false;
public UnitOfWork(IDbContextFactory contextFactory)
{
_context = contextFactory.GetContext();
}
public void SaveChanges()
{
if (_context != null)
{
_context.SaveChanges();
}
}
public DbContext Context
{
get { return _context; }
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
_context.Dispose();
}
}
disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
Service
public class CompanyService
{
private readonly IUnitOfWork _uow;
private readonly IEmployeeRepository _employeeRepository;
private readonly ICustomerRepository _customerRepository;
public CompanyService(IUnitOfWork uow, IEmployeeRepository employeeRepository, ICustomerRepository customerRepository)
{
_uow = uow;
_employeeRepository = employeeRepository;
_customerRepository = customerRepository;
}
// over-simplified example method
public void AddEmployeeAndCustomer()
{
_employeeRepository.Create(new Employee {Id = 1, Name = "Test Employee"});
_customerRepository.Create(new Customer { Id = 2, Name = "Test Customer" });
_uow.SaveChanges();
}
}
I think what you are looking for is a per request lifetime manager so that you only get one UnitOfWork instance and one DbContext instance for the duration of a request. Unity 3 has the Unity bootstrapper for ASP.NET MVC which has a PerRequestLifetimeManager which lets you do this.
If you are not using ASP.NET then you could probably use a PerResolveLifetimeManager. Another approach I've seen is a HierarchicalLifetimeManager combined with a child container (which makes the registrations a singleton within the child container).

Parameterless implementation for Ninject mappings

i am creating custom membership provider using ninject for binding to sql classes.
my class in looks like
public MyMembershipProvider(IUsersRepository userRepository)
{
this.userRepository = userRepository;
}
How can i create from this parameterless constructor?
kernel.Bind<IUsersRepository>().To<UsersRepository>();
kernel.Bind<MembershipProvider>().To<MyMembershipProvider>();
and then:
public class AccountController : Controller
{
private readonly MembershipProvider _membershipProvider;
public AccountController(MembershipProvider membershipProvider)
{
_membershipProvider = membershipProvider;
}
public ActionResult Foo()
{
// TODO: Use the membership provider to do some processing
return View();
}
}