1

如何将以下 Ninject DI 转换为 LightInject DI 的等效项?我在使用正确的语法时遇到问题。

Database.SetInitializer(new MigrateDatabaseToLatestVersion<DefaultMembershipRebootDatabase, BrockAllen.MembershipReboot.Ef.Migrations.Configuration>());

kernel.Bind<UserAccountService>().ToSelf();
kernel.Bind<AuthenticationService>().To<SamAuthenticationService>();
kernel.Bind<IUserAccountQuery>().To<DefaultUserAccountRepository>().InRequestScope();
kernel.Bind<IUserAccountRepository>().To<DefaultUserAccountRepository>().InRequestScope();

在我最初的问题上,我没有包括这个,但是这个(也作为评论发布到这个帖子)是我试图让它工作的无效代码:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<DefaultMembershipRebootDatabase, BrockAllen.MembershipReboot.Ef.Migrations.Configuration>());

container.Register<UserAccountService>();
container.Register<AuthenticationService, SamAuthenticationService>();
container.Register<IUserAccountQuery, DefaultUserAccountRepository>(new PerRequestLifeTime());
container.Register<IUserAccountRepository, DefaultUserAccountRepository>(new PerRequestLifeTime());

给出的错误消息(没有堆栈跟踪)是这样的:

异常详细信息:System.InvalidOperationException:未解决的依赖项 [目标类型:BrockAllen.MembershipReboot.Ef.DefaultUserAccountRepository]、[参数:ctx(BrockAllen.MembershipReboot.Ef.DefaultMembershipRebootDatabase)]、[请求的依赖项:ServiceType:BrockAllen.MembershipReboot.Ef.DefaultMembershipRebootDatabase , 服务名称:]

源错误:

在执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常起源和位置的信息。

*如果有人也想查看堆栈跟踪 - * 只要问,我会在回复这个问题时发布。

DefaultMembershipRebootDatabase 的构造函数(就像在示例项目中一样,我的项目使用了通过 nuget 提供的 dll,构造函数不可用,但我很确定它们在这两种情况下很可能相同(看看如何它来自同一个来源......)是:

public class DefaultMembershipRebootDatabase : MembershipRebootDbContext<RelationalUserAccount>
{
    public DefaultMembershipRebootDatabase()
        : base()
    {
    }

    public DefaultMembershipRebootDatabase(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {
    }

    public DefaultMembershipRebootDatabase(string nameOrConnectionString, string schemaName)
        : base(nameOrConnectionString, schemaName)
    {
    }
}

这是 DefaultUserAccountRepository 的构造函数(与前面提到的同一个示例项目一样):

public class DefaultUserAccountRepository
       : DbContextUserAccountRepository<DefaultMembershipRebootDatabase, RelationalUserAccount>, 
         IUserAccountRepository
{
    public DefaultUserAccountRepository(DefaultMembershipRebootDatabase ctx)
        : base(ctx)
    {
    }

    IUserAccountRepository<RelationalUserAccount> This { get { return (IUserAccountRepository<RelationalUserAccount>)this; } }

    public new UserAccount Create()
    {
        return This.Create();
    }

    public void Add(UserAccount item)
    {
        This.Add((RelationalUserAccount)item);
    }

    public void Remove(UserAccount item)
    {
        This.Remove((RelationalUserAccount)item);
    }

    public void Update(UserAccount item)
    {
        This.Update((RelationalUserAccount)item);
    }

    public new UserAccount GetByID(System.Guid id)
    {
        return This.GetByID(id);
    }

    public new UserAccount GetByUsername(string username)
    {
        return This.GetByUsername(username);
    }

    UserAccount IUserAccountRepository<UserAccount>.GetByUsername(string tenant, string username)
    {
        return This.GetByUsername(tenant, username);
    }

    public new UserAccount GetByEmail(string tenant, string email)
    {
        return This.GetByEmail(tenant, email);
    }

    public new UserAccount GetByMobilePhone(string tenant, string phone)
    {
        return This.GetByMobilePhone(tenant, phone);
    }

    public new UserAccount GetByVerificationKey(string key)
    {
        return This.GetByVerificationKey(key);
    }

    public new UserAccount GetByLinkedAccount(string tenant, string provider, string id)
    {
        return This.GetByLinkedAccount(tenant, provider, id);
    }

    public new UserAccount GetByCertificate(string tenant, string thumbprint)
    {
        return This.GetByCertificate(tenant, thumbprint);
    }
}

这是我项目中的控制器:

namespace brockallen_MembershipReboot.Controllers
{
using System.ComponentModel.DataAnnotations;

using BrockAllen.MembershipReboot;
using BrockAllen.MembershipReboot.Mvc.Areas.UserAccount.Models;

public class UserAccountController : Controller
{
    UserAccountService _userAccountService;
    AuthenticationService _authService;

    public UserAccountController(AuthenticationService authService)
    {
        _userAccountService = authService.UserAccountService;
        _authService = authService;
    }

    // GET: /UserAccount/
    [Authorize]
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Login()
    {
        return View(new LoginInputModel());
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginInputModel model)
    {
        if (ModelState.IsValid)
        {
            /*BrockAllen.MembershipReboot.*/UserAccount account;
            if (_userAccountService.AuthenticateWithUsernameOrEmail(model.Username, model.Password, out account))
            {
                _authService.SignIn(account, model.RememberMe);

                _authService.SignIn(account, model.RememberMe);

                /*if (account.RequiresTwoFactorAuthCodeToSignIn())
                {
                    return RedirectToAction("TwoFactorAuthCodeLogin");
                }
                if (account.RequiresTwoFactorCertificateToSignIn())
                {
                    return RedirectToAction("CertificateLogin");
                }

                if (_userAccountService.IsPasswordExpired(account))
                {
                    return RedirectToAction("Index", "ChangePassword");
                }*/

                if (Url.IsLocalUrl(model.ReturnUrl))
                {
                    return Redirect(model.ReturnUrl);
                }

                return RedirectToAction("Index");
            }
            else
            {
                ModelState.AddModelError("", "Invalid Username or Password");
            }
        }

        return View(model);
    }

    public ActionResult Register()
    {
        return View(new RegisterInputModel());
    }

    [ValidateAntiForgeryToken]
    [HttpPost]
    public ActionResult Register(RegisterInputModel model)
    {
        if (ModelState.IsValid)
        {
            try
            {
                var account = _userAccountService.CreateAccount(model.Username, model.Password, model.Email);
                ViewData["RequireAccountVerification"] = _userAccountService.Configuration.RequireAccountVerification;
                return View("Success", model);
            }
            catch (ValidationException ex)
            {
                ModelState.AddModelError("", ex.Message);
            }
        }
        return View(model);
    }
}
}

AuthenicationService 的构造函数是:

public abstract class AuthenticationService : AuthenticationService<UserAccount>
{
    public new UserAccountService UserAccountService
    {
        get { return (UserAccountService)base.UserAccountService; }
        set { base.UserAccountService = value; }
    }

    public AuthenticationService(UserAccountService userService)
        : this(userService, null)
    {
    }

    public AuthenticationService(UserAccountService userService, ClaimsAuthenticationManager claimsAuthenticationManager)
        : base(userService, claimsAuthenticationManager)
    {
    }
}
4

2 回答 2

2

默认情况下,LightInject 不会在不注册具体类的情况下解析它们,而 NInject 会。

例如,NInjectDefaultMembershipRebootDatabase无需注册即可解析,而 LightInject 默认无法解析。看看这个

无论如何,要解决您的问题,请确保注册您的具体类(作为其他类中的依赖项需要)。这是一个例子:

container.Register<DefaultMembershipRebootDatabase>();

我在这里假设某个类依赖于具体类DefaultMembershipRebootDatabase。如果您有其他具体的类依赖项,请确保您也注册了它们。

于 2015-12-24T17:37:11.060 回答
2

您应该使用 PerScopeLifetime 而不是 PerRequestLifetime。PerRequestLifetime 表示一个临时生命周期,它跟踪一次性实例并在作用域结束时释放它们。PerScopeLifetime 确保范围内的相同实例,在这种情况下意味着 Web 请求中的相同实例。

于 2015-12-25T10:13:27.317 回答