JasperFx / lamar

Fast Inversion of Control Tool and Successor to StructureMap
https://jasperfx.github.io/lamar
MIT License
572 stars 119 forks source link

A local variable or function named 'repository2' is already defined in this scope #92

Closed wiggydave10 closed 6 years ago

wiggydave10 commented 6 years ago

Recently I discovered a problem where we're trying to use 4 repositories in a service caused compilation errors. It seems as though when it's creating the repositories the local variables are being duplicated, 2x repository1 and 2x repository2.

I've tried reproducing the problem in a brand new test project and I get the same results. I notice that if I inject 4 services, each with there own interface, I do not have this issue, but once injecting 4 services/repositories with the same generic interface the problem occurs. The error produced by lamar is at the bottom.

Please see attached project to assist with reproduction of issue. You should just be able to run the project with IIS Express and once the page has loaded you'rll see the error message.

I have a .NET Core 2.1 web app, Lamar 1.1.2 and Lamar.Microsoft.DependencyInjection 1.1.2

UserService.cs that lamar cannot create cannot create

public class UserService : IUserService
    {
        private IRepository<User> userRepo;
        private IRepository<UserAudit> userAuditRepo;
        private IRepository<UserDecision> userDecisionRepo;
        private IRepository<UserMessage> userMessageRepo;

        public UserService(IRepository<UserMessage> userMessageRepo, IRepository<UserDecision> userDecisionRepo, IRepository<UserAudit> userAuditRepo, IRepository<User> userRepo)
        {
            this.userMessageRepo = userMessageRepo;
            this.userDecisionRepo = userDecisionRepo;
            this.userAuditRepo = userAuditRepo;
            this.userRepo = userRepo;
        }

        public void FindByUsername(string username)
        {
        }
    }

Error shown by lamar:

An unhandled exception occurred while processing the request.
InvalidOperationException: Compilation failures!

CS0128: A local variable or function named 'repository2' is already defined in this scope
CS0128: A local variable or function named 'repository1' is already defined in this scope
CS1503: Argument 1: cannot convert from 'LamarBugTesting.Web.Services.Repository<LamarBugTesting.Web.Domain.UserAudit>' to 'LamarBugTesting.Web.Services.IRepository<LamarBugTesting.Web.Domain.UserMessage>'
CS1503: Argument 2: cannot convert from 'LamarBugTesting.Web.Services.Repository<LamarBugTesting.Web.Domain.User>' to 'LamarBugTesting.Web.Services.IRepository<LamarBugTesting.Web.Domain.UserDecision>'

Code:

using System.Threading.Tasks;

namespace Jasper.Generated
{
// START: LamarBugTesting_Web_Services_IUserService_userService
public class LamarBugTesting_Web_Services_IUserService_userService : Lamar.IoC.Resolvers.TransientResolver<LamarBugTesting.Web.Services.IUserService>
{

public override LamarBugTesting.Web.Services.IUserService Build(Lamar.IoC.Scope scope)
{
var repository2 = new LamarBugTesting.Web.Services.Repository<LamarBugTesting.Web.Domain.User>();
var repository1 = new LamarBugTesting.Web.Services.Repository<LamarBugTesting.Web.Domain.UserAudit>();
var repository2 = new LamarBugTesting.Web.Services.Repository<LamarBugTesting.Web.Domain.UserDecision>();
var repository1 = new LamarBugTesting.Web.Services.Repository<LamarBugTesting.Web.Domain.UserMessage>();
return new LamarBugTesting.Web.Services.UserService(repository1, repository2, repository1, repository2);
}

}

// END: LamarBugTesting_Web_Services_IUserService_userService

}

Lamar.Compilation.AssemblyGenerator.Generate(string code)

LamarBugTesting.zip

jeremydmiller commented 6 years ago

@wiggydave10 Thanks for the bug report. I'll try to make a sweep of Lamar issues tomorrow and over the weekend to get this one address (won't be any big deal, I'll just make the naming use the generic arg to avoid the collisions).

However, I'd strongly advise against the IRepository<T> thing though, but that has nothing to do with Lamar.

wiggydave10 commented 6 years ago

@jeremydmiller Thanks. I've since changed and no longer need to pass the in IRepository<T>, but thought I'd still report. Out of interest could you elaborate on why you strongly advise against using the IRepository<T>?

MaasRob commented 6 years ago

Is there a fix coming up for this problem, I'm running into it as well. Plus I'm also interested in why it is you strongly advice against using IRepository, or IAsyncRepository for that matter?

Thanks you in advance!

jeremydmiller commented 6 years ago

@wiggydave10 Yes (worked on it a touch last night), and the IRepository<T> just adds too much ceremony for new real value to me. It forces you to create all those little objects and hides all the power and most of the functionality of your data access tool.

jeremydmiller commented 6 years ago

Finally.