Search code examples
c#.netioc-containerunity2.0

Unity Application Block, How pass a parameter to Injection Factory?


Here what I have now

  Container.RegisterType<IUserManager, UserManagerMock>();
  Container.RegisterType<IUser, UserMock>(
                new InjectionFactory(
                    (c) => c.Resolve<IUserManager>().GetUser("John")));

and get it

Container.Resolve<IProfile>();

I want to pass a name as parameter to Factory so that I will be able to resolve user object with name; Something like this:

 Container.Resolve<IProfile>("Jonh");

How can I change the type registration for this case?


Solution

  • While most DI frameworks have advanced features to do these types of registrations, I personally rather change the design of my application to solve such a problem. This keeps my DI configuration simple and makes the code easier to understand. Especially for the creation of objects that depend on some context (thread, request, whatever) or have a lifetime that must be managed explicitly, I like to define factories. Factories make these things much more explicit.

    In your situation, you want to fetch a profile for a certain user. This is typically something you would like to have a factory for. Here's an example of this:

    // Definition
    public interface IProfileFactory
    {
        IProfile CreateProfileForUser(string username);
    }
    
    // Usage
    var profile = Container.Resolve<IProfileFactory>()
        .CreateProfileForUser("John");
    
    // Registration
    Container.RegisterType<IProfileFactory, ProfileFactory>();
    
    // Mock implementation
    public class ProfileFactory : IProfileFactory
    {
        public IProfile CreateProfileForUser(string username)
        {
            IUser user = Container.Resolve<IUserManager>()
                .GetUser(username);
    
            return new UserProfile(user);
        }
    }
    

    I hope this helps.