Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
469 views
in Technique[技术] by (71.8m points)

dependency injection - How to inject webapi AccountController in WebApi

I have default constuctor and constructor with params like here:

public class AccountController : ApiController
{
    private const string LocalLoginProvider = "Local";
    private ApplicationUserManager _userManager;
    public ISecureDataFormat<AuthenticationTicket> AccessTokenFormat { get; private set; }
    [Dependency]
    public IRepository Repository{ get; private set; }

    public AccountController()
    {
    }

    public AccountController(ApplicationUserManager userManager, ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
    {
        _userManager = userManager;
        AccessTokenFormat = accessTokenFormat;
    }
}

And my unity config here:

.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager())
.RegisterType<UserManager<ApplicationUser, int>, ApplicationUserManager>()                
.RegisterType<ApplicationDbContext>(new HierarchicalLifetimeManager())
.RegisterType<ApplicationUserManager>()

.RegisterType<ISecureDataFormat<AuthenticationTicket>, SecureDataFormat<AuthenticationTicket>>()
.RegisterType<ITextEncoder, Base64UrlTextEncoder>()
.RegisterType<IDataSerializer<AuthenticationTicket>, TicketSerializer>()
//.RegisterType<IDataProtector>(() => new DpapiDataProtectionProvider().Create("ASP.NET Identity"))

.RegisterType<IUserStore<ApplicationUser, int>, CustomUserStore>(new InjectionConstructor(typeof(ApplicationDbContext)))
.RegisterType<IAuthenticationManager>(new InjectionFactory(o => HttpContext.Current.GetOwinContext().Authentication))
.RegisterType<IOwinContext>(new InjectionFactory(o => HttpContext.Current.GetOwinContext()))
.RegisterType<IRepository, Repository>();

But the thing is that default constructor is always getting called. I read taht article blog but they not talking how to resolve such case with constructor havaving params AccountController(ApplicationUserManager userManager, ISecureDataFormat<AuthenticationTicket> accessTokenFormat)

If I am taking off parameterless constructor I am getting an error: "An error occurred when trying to create a controller of type 'AccountController'. Make sure that the controller has a parameterless public constructor.", Is there anyone can help?

Also I have just normal ApiController and i is not getting injected as well:

public class MyController : ApiController
{
    [Dependency]
    public IRepository Repository { get; set; }

    public IHttpActionResult Get()
    {
        var test = Repository.GetSomething(); // Repository is null here always
    }
}

UPDATE 1 Based on @IgorPashchuk suggeston now MyController is getting injected now. But AccoutController is not. I am removed the default constructor but still getting the error.

UPDATE 2 I alter the constructor with params by taking out the second param:

public class AccountController : ApiController
{
    private const string LocalLoginProvider = "Local";
    private ApplicationUserManager _userManager;

    [Dependency]
    public IRepository Repository{ get; private set; }

    public AccountController(ApplicationUserManager userManager)
    {
        _userManager = userManager;
    }
}

So this way I've got the thing is working. Is I understand that is means that Unity wasnt able to construct type ISecureDataFormat<AuthenticationTicket>. I post another question about this issue How to construct ISecureDataFormat<AuthenticationTicket> with unity

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You should remove the parameterless constructor.

Next, you need to configure a custom dependency resolver, which will basically wrap your Unity container. See http://www.asp.net/web-api/overview/advanced/dependency-injection

After that, make sure that you register all your types. For example, I don't see a registration for ApplicationUserManager. You are registering UserManager<ApplicationUser, int> but not ApplicationUserManager, which is what the IoC container will attempt to resolve.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...