0
votes

My source is at https://github.com/tonyeung/generic-repo

I want to create a generic repository that I can reference in different projects. Most generic repository implementations that I've seen make that difficult. I stumbled across http://blog.damianbrady.com.au/2012/07/24/a-generic-repository-and-unit-of-work-implementation-for-entity-framework/ and found that it would work great for what I have in mind. Each of my projects can have a context defined in it, then I just need to reference a generic repository project or dll and pass in the context and I'm ready to go.

The only thing I'm trying to get my head around is how do I wire structuremap since there are a few nested dependencies that need to get resolved. Unfortunately, the blog doesn't really address how to implement dependency injection with the generic repository. I tried to tinker around with the implementation (see above referenced git hub repo), but I'm doing something wrong while configuring structure map.

The dependencies work out like this: the repository takes a context in the constructor, and the context in turn gets a connection string. The constructor parameters are all interfaces which match the default convention of IType maps to Type. My assumption is that since I have auto registration, all I need to do is explicitly define the registration for the context to tell structuremap that it should get the connection string from the app.config, I should be good to go.

However, structuremap is not able to work out the registrations like I thought it would:

StructureMap Exception Code:  202
No Default Instance defined for PluginFamily Generic_Repository_Test.IGenericRepository`1
    [[ViewModel.Customer, ViewModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], 
    Generic Repository Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

The registration code

        //This is commented out since it should not be necessary.
        //I tried to put this in for grins
        //and see if it would resolve the issue but it doesn't.
        //For<IGenericRepository<Customer>>().Use<GenericRepository<CustomerContext, Customer>>();

        For<ICustomerContext>()
                .Use<CustomerContext>()
                .Ctor<string>("connectionString")
                .EqualToAppSetting("ConnectionString");

        //I've tried moving scan to the top but it didn't make a difference
        Scan(x =>
        {
            x.AssembliesFromApplicationBaseDirectory();
            x.WithDefaultConventions();
        });
1

1 Answers

0
votes

The problem did in fact turn out to be a configuration issue. The issue was that the app.settings connectionstring setting was returning null, I'm not sure why that happens but I hardcoded the connection string just for grins. Will figure that issue out later.

With that resolved, I still had to manually configure the repo and the context, since another error popped up.

With that resolved, it looks like structuremap was trying to resolve itself, so I had to add a namespace exclusion.

The completed code looks like this:

public class DependencyRegistry : Registry
{
    public DependencyRegistry()
    {
        For<ICustomerContext>()
                .Use<CustomerContext>()
                .Ctor<string>("connectionString")
            //.EqualToAppSetting("ConnectionString");
                .Is(@"Data Source=(localdb)\Projects;Initial Catalog=EventStorage;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False");
        For<IGenericRepository<Customer>>().Use<GenericRepository<ICustomerContext, Customer>>();


        Scan(x =>
        {
            x.AssembliesFromApplicationBaseDirectory();
            x.ExcludeNamespace("StructureMap");
            x.WithDefaultConventions();
        });
    }
}