开发者

Ninject constructor argument

I have this interface:

public interface IUserProfileService
{
    // stuff
}

Implemented by:

public class UserProfileService : IUserProfileService
{
    private readonly string m_userName;

    public UserProfileService(string userName)
    {
        m_userName = userName;
    }
}

I need this injected into a controller like this:

public class ProfilesController : BaseController
{
    private readonly IUserProfileService m_profileService;

    public ProfilesController(IUserProfileService profileService)
    {
        m_profileService = profileService;
    }
}

I don't know how I can register this interface and its implementation into Ninject 开发者_开发问答container so that userName param is passed in when the Ninject inits an instance of this service.

Any ideas how I can achieve this?


The technical ninject answer is to use constructor arguments like so:

Bind<IUserProfileService>().To<UserProfileService>().WithConstructorArgument("userName", "karl");

Of course you need to figure out where "karl" comes from. It really depends on your app. Maybe its a web app and it's on the HttpContex? I don't know. If it gets rather complicated then you might want to write a IProvider rather than doing a regular binding.


One alternative is to inject a factory and create your dependency using Create(string userName).

public class UserProfileServiceFactory
{
    public IUserProfileService Create(string userName)
    {
        return new UserProfileService(userName);
    }
}

It might seem off to have to create another class but the benefits mostly comes when UserProfileService takes in additional dependencies.


The trick is to not inject the username in that class. You call this class a service so it would probably work transparantly with multiple users. I see two solutions:

  1. Inject an abstraction into the service that represents the current user:

    public class UserProfileService : IUserProfileService
    {
        private readonly IPrincipal currentUser;
    
        public UserProfileService(IPrincipal currentUser)
        {
            this.currentUser = currentUser;
        }
    
        void IUserProfileService.SomeOperation()
        {
            var user = this.currentUser;
    
            // Do some nice stuff with user
        }
    }
    
  2. Create an implementation that is specific to the technology you are working with, for instance:

    public class AspNetUserProfileService : IUserProfileService
    {
        public AspNetUserProfileService()
        {
        }
    
        void IUserProfileService.SomeOperation()
        {
            var user = this.CurrentUser;
    
            // Do some nice stuff with user
        }
    
        private IPrincipal CurrentUser
        {
            get { return HttpContext.Current.User; }
        }
    }
    

If you can, go with option one.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜