1
votes

I have one base generic repository and many class repository that inherits from the base repository. I need too pass string value to the generic repository.

Here is my Generic Repository

public class Repository<T> where T : EntityBase
    {
        private string SessionId;

        public Repository(string sessionId)
        {
            this.SessionId = sessionId;
        }

        protected virtual IDbConnection GetCn()
        {
            return new SqlConnection(ConfigurationManager.ConnectionStrings["SalesDb"].ConnectionString);
        }

        public virtual int Insert(T entity)
        {
            entity.ChUser = "anders.persson";
            entity.ChTime = DateTime.Now;

            using (IDbConnection cn = GetCn())
            {
                cn.Open();

                return cn.Insert(entity);
            }
        }

        // MORE CODE
        }
    }

And the interface

public interface IRepository<T>
{
    int Insert(T entity);

}

My Class Repository

public class MarketRepository : Repository<Market>, IMarketRepository
    {

    }

And the interface

public interface IMarketRepository : IRepository<Market>
{

}

Now i want to pass sessionId to the Generic Repositories constructor. How can i do that. In this case i have to implement a constructor in every class repository and pass it to the base repository. And the interface dont even know about that constructor.

Here is the Ninject bindings

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>));
    kernel.Bind<ILeadRepository>().To<LeadRepository>();
    kernel.Bind<IPricelistRepository>().To<PricelistRepository>();
    kernel.Bind<IOptionalGroupRepository>().To<OptionalGroupRepository>();
    kernel.Bind<IProductGroupRepository>().To<ProductGroupRepository>();
    kernel.Bind<IProductRepository>().To<ProductRepository>();
    kernel.Bind<IMarketRepository>().To<MarketRepository>();
    kernel.Bind<IModelRepository>().To<ModelRepository>();
    kernel.Bind<IOrderRepository>().To<OrderRepository>();
}  
2

2 Answers

2
votes

You can add it to a binding:

Bind<IMarketRepository>().To<MarketRepository>().WithConstructorArgument("sessionId", "Session ID here");
2
votes

The sessionId would be a runtime value, so you'll want to pass it to the ctor when resolving.
The syntax to do that is:

var reposetory 
    = kernel.Get<IMarketRepository>(new ConstructorArgument("sessionId", sessionId));

Given that you don't want to use a Service Locator, calling Get directly, and use ctor injection instead, you can encapsulate that inside a factory.

Configuration:

kernel.Bind<IRepositoryFactory>().To<RepositoryFactory>()
      .WithConstructorArgument("kernel", kernel);

Factory:

public class RepositoryFactory : IRepositoryFactory
{
    private IKernel _kernel;

    public RepositoryFactory(IKernel kernel)
    {
        _kernel = kernel;
    }

    public T CreateNew<T>(string sessionId)
    {
        return
            _kernel.Get<T>(new ConstructorArgument("sessionId", sessionId));
    }
}

Usage:

var repository = _repositoryFactory.CreateNew<IMarketRepository>(sessionId);