3

I am out to sea with this.

I received this answer which was corrected here by Nkosi.. however whilst it indicated how to rewrite the factory I am not up to the task of implementing it.. I need some gaps filled in.

As I understand it, this is what I need to do..

define the interface:

public interface IContextFactory<TContext> where TContext : DbContext 
{
    TContext Create(string connectionString);
}

Create the factory:

public class ContextFactory<TContext> : IContextFactory<TContext>
    where TContext : DbContext
{
    public TContext Create(DbContextOptions<TContext> options)
    {
        return (TContext)Activator.CreateInstance(typeof(TContext), options);
    }
}

register the factory as a singleton in startup.

This is what I did and I dont know if this is correct?

services.AddSingleton(typeof(IContextFactory<>), typeof(ContextFactory<>));

Next how the heck do I use this factory?

In the first answer, it was suggested I use this:

public class EntityBaseRepository<T> : IEntityBaseRepository<T> where T : class, IEntityBase, new()
{
    private JobsLedgerAPIContext _context;

    public string ConnectionString { get; set; }

    public EntityBaseRepository(IContextFactory<JobsLedgerAPIContext> factory)
    {
        _context = factory.CreateDbContext(ConnectionString);
    }

    public virtual IQueryable<T> GetAll()
    {
        return _context.Set<T>().AsQueryable();
    }

    public virtual int Count()
    {
        return _context.Set<T>().Count();
    }
}

Nkosi identified that you cannot have the constraint "new()" and a parameterized constructor. He rewrote it. How do I change the above code to reflect the fact the factory now does not have a parameterized constructor but still take in the connection string given Nkosi's factory?

ClientRepository inherits the above.

public class ClientRepository : EntityBaseRepository<Client>, IClientRepository
{
    private new JobsLedgerAPIContext _context;

    public ClientRepository(JobsLedgerAPIContext context) : base(context)
    {
        _context = context;
    }

Does this constructor need to be changed.

And finally how do I Inject the ClientRepository now that I have to supply a connection string?

5
  • 1
    I think you should ignore answers to all your previous questions and start over. There is no need to modify the services / repositories having LobsLedgerAPIContext dependency. What you need is to make that context dependent of some service providing the information about the current logged in user - similar to AppTenant from ASP.NET Core Multi-tenancy: Data Isolation with Entity Framework Commented Apr 28, 2019 at 10:04
  • 1
    Ivan's suggestion is sound and would really simplify the design that was originally suggested to you. As part of your auth process you could add the connection string as a claim on the current user principle. From there you can inject details into the context that will use it in OnConfiguring just like in the linked article. Commented Apr 28, 2019 at 11:21
  • 1
    The answer I provided you was just to fix the syntax issues in the suggested answer you got. I personally would not have gone with the design as it abstracts for abstraction sake and over complicates tings unnecessarily. Commented Apr 28, 2019 at 11:24
  • 2
    This appears to be a classic XY problem. Commented Apr 28, 2019 at 11:29
  • @si2030 could you solve this problem. now, ıhave a problem like it :( if you could solve your problem, can you help me ? Commented Sep 1, 2020 at 19:24

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.