Drax
Drax

Reputation: 63

Dependency Injection via constructor create only one instance

I would like to ask how to create a proper Dependency Injection via constructor to create a list of unique object. Now i have this kind of situation: 1) I adding an object to the list of my objects, however each subsequent overwrite all previous one (i.e. it is not unique). 2) I refer to the factory class statically. However in this case i do not use a dependency injection in constructor of this interface.

Is there any other solution possible.

Thanks for all answers.

Example it is not 100% same code (because my list is also initialized by constructor):

 class GetUserFirstOption
        {
            IUser _user;
            GetUserFirstOption(IUser user)
            {
                _user = user;
            }

            public void UsersInCompany()
            {
                //Here is connection to the database where i upload 500 records to UsersFromDataBase

                List<User> UsersInCompany = new List<User>();
                foreach (var userDB in UsersFromDataBase)
                {
                    _user.Name = userDB.Name;
                    _user.SecondName = userDB.SecondName;
                    //...

                    UsersInCompany.Add(_user);
                    //Here i have 500 users but all same

                }
            }
        }



      class GetUserSecondOption
        {
            public void UsersInCompany()
            {
                List<User> UsersInCompany = new List<User>();
                foreach (var userDB in UsersFromDataBase)
                {
                    _user = Factory.CreateNewUser();
                    _user.Name = userDB.Name;
                    _user.SecondName = userDB.SecondName;
                    //...

                    UsersInCompany.Add(_user);
                    //I have 500 unique records but i do not need to it dependency injection

                }
            }
        }



class Factory
{
   public static IGetUserSecondOption CreateUserInCompany()
   {
      return new GetUserSecondOption(UserFactory.CreateNewUser());
   }
}

class UserFactory
{
  public static IUser CreateNewUser()
  {
      return new User();
  }
}


class Program
{
  public static Main(string []args)
  {            
    IGetUserSecondOption Get = Factory.Factory.CreateUserInCompany();
    Get.UserInCompany();
   }        
}

Upvotes: 0

Views: 937

Answers (2)

Nkosi
Nkosi

Reputation: 246998

Having a factory here seem like a code smell and in my opinion over engineering.

Reference Abstract Factories are a Code Smell

Referring to the factory statically creates tight coupling, that can have unwanted results when trying to unit test in isolation. The class is also not being genuine about what it needs to perform its designed function.

Reference Explicit Dependencies Principle

The creation of a model for the purpose of persistence where there are no knock on or adverse effect of simply creating the instance and populating its members really does not need the additional complexity of a factory abstraction.

public void UsersInCompany() {
    List<User> UsersInCompany = new List<User>();
    foreach (var userDB in UsersFromDataBase) {
        User user = new User() {
            Name = userDB.Name,
            SecondName = userDB.SecondName,
            //...
        };
        UsersInCompany.Add(user);    
    }
}

There are also services like Automapper that could be used to simplify the process

public class UsersService {
    private readonly IMapper mapper;

    public UsersService(IMapper mapper) {
        this.mapper = mapper
    }

    public List<User> UsersInCompany() {            
        List<User> UsersInCompany = new List<User>();
        foreach (var userDB in UsersFromDataBase) {
            User user = mapper.Map<User>(userDb);
            UsersInCompany.Add(user);
        }
        return UsersInCompany;
    }
}

The IUser also appears to be an abstraction of a data model, which might indicate a misunderstanding of the principles, but as the question is a simplified example, I may stand corrected if the situation is way more complex than first indicated.

Upvotes: 1

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

Instead of injecting a user to your loop, create a factory that creates users. Then you may inject the factory instead:

class GetUserSecondOption
{
    public GetUserSecondOption(UserFactory factory) { this.Factory = factory; }
    public void UsersInCompany()
    {
        List<User> UsersInCompany = new List<User>();
        foreach (var userDB in UsersFromDataBase)
        {
            var user = this.Factory.CreateNewUser();
            user.Name = userDB.Name;
            user.SecondName = userDB.SecondName;
            //...

            UsersInCompany.Add(user);    
        }
    }
}

Upvotes: 1

Related Questions