Ninject - Setting dependencies constructor with run-time value

╄→гoц情女王★ 提交于 2019-12-12 02:46:19

问题


I'm fairly new to DI/Ninject and I can't seem to figure out what I need to do. I have a service like this:

public class ArchiveService : IArchiveService
{
    private string sAuditUser = "USER";

    public ArchiveService(string AuditUser)
    {
        sAuditUser = AuditUser;
    }
    ...
}

I'm currently instantiated the service like this:

string sUser = HttpContext.Session["UID"].ToString();
ArchiveService svcArchive = new ArchiveService(Session["UID"].ToString());

The session value gets set when a user successfully logs in on the account page. How can I setup the service dependency so it will get that value properly?


回答1:


In general you should try to prevent trying to inject primitive values into services unless:

  • They are configuration values, -and-
  • They only have to be injected into a single service.

If either of those are false, you should not inject the primitive directly.

In your case you're dealing with context information and that deserves its own abstraction:

public interface IUserContext
{
    string Name { get; }
}

With this abstraction in place, all services that need to know anything about the current user on who's behalf the operation is executing, can depend on this abstraction.

public class ArchiveService : IArchiveService
{
    private IUserContext userContext;

    public ArchiveService(IUserContext userContext)
    {
        this.userContext = userContext;
    }
}

The only thing you have to do now is to create an IUserContext implementation that you register. How this implementation looks like totally depends on the type of application you are running (ASP.NET, Win Forms, WCF, etc), but in your particular case, this is how it would be implemented:

public class AspNetUserContext : IUserContext
{
    public string Name
    { 
       get
       {
           return HttpContext.Current.Session["UID"].ToString();
       }
    }
}

And this is how you register it:

Bind<IUserContext>().To<AspNetUserContext>().InSingletonScope();

It might seem silly to create an interface for a single string, but it has some clear advantages:

  • The new abstraction communicates much clearer what that value is. A string could be anything. It could be a path, a connection string, etc.
  • The abstraction centralized the knowledge of how to get this user information to a single place.
  • Since the new abstraction is unambiguous, it becomes much easier to register this in the container. The configuration will be much more maintainable.
  • The solution is much less error prone, because we centralized the way user information is provided.


来源:https://stackoverflow.com/questions/18279427/ninject-setting-dependencies-constructor-with-run-time-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!