Я пытаюсь написать общее консольное приложение .Net Core 2.2, которое позволяет мне использовать Identity. В частности, у меня есть база данных, и я просто пытаюсь вызвать SignInManager.PasswordSignInAsync () для аутентификации имени пользователя и пароля в моей БД.
Если я запускаю это в полномасштабном .NetCore WebApp, где HttpContext и DI все построены, это прекрасно работает. Если я урежу его и просто позвоню в базовые службы, я получаю одну и ту же ошибку каждый раз.
Я пробовал варианты уже несколько дней и просто не могу понять, что мне не хватает.
Любая помощь будет принята с благодарностью.
У меня есть класс, который управляет компоновкой служб, доступных для консольного приложения.
public class FXLoginProvider
{
private readonly IServiceCollection _svccoll;
private UserManager<FXUser> _um = null;
private SignInManager<FXUser> _sm = null;
public UserManager<FXUser> UserMgr
{
get { return _um ?? (_um = _svccoll.BuildServiceProvider().GetService<UserManager<FXUser>>()); }
}
public SignInManager<FXUser> SignInMgr
{
get { return _sm ?? (_sm = _svccoll.BuildServiceProvider().GetService<SignInManager<FXUser>>()); }
}
public FXLoginProvider()
{
string s = "Data Source=.\\SQLEXPRESS;Initial catalog=csNextGen;Integrated Security=True;TrustServerCertificate=True;ApplicationIntent=ReadWrite";
_svccoll = new ServiceCollection();
_svccoll.AddDbContext<FXDataContext>(options => { options.UseSqlServer(s); });
_svccoll.AddIdentity<FXUser, FXUserRole>().AddDefaultTokenProviders();
_svccoll.AddTransient<IUserStore<FXUser>, FXUserStore>();
_svccoll.AddTransient<IRoleStore<FXUserRole>, FXRoleStore>();
_svccoll.AddLogging();
_svccoll.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
}
Тогда в моем главном приложении ...
class Program
{
static void Main(string[] args)
{
try
{
FXUser uu = null;
string sUsername = "user";
string sPassword = "P$sSw0rrD#!";
// create the service provider
FXLoginProvider icp = new FXLoginProvider();
// grab the sign in manager
SignInManager<FXUser> sm1 = icp.SignInMgr;
// fetch the user from the db, this works.
uu = icp.UserMgr.FindByNameAsync(sUsername).Result;
// update my security stamp, this works too
sm1.UserManager.UpdateSecurityStampAsync(uu).GetAwaiter().GetResult();
// I was receiving a Null context error, so I added a default context.
sm1.Context = new DefaultHttpContext();
var r = sm1.PasswordSignInAsync(sUsername, sPassword, false, false).GetAwaiter().GetResult();
Console.WriteLine(r);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
и всегда выдает одно и то же исключение:
Значение не может быть пустым. \ R \ nИмя параметра: поставщик
Я вижу в StackTrace, что он сбрасывает в DependencyInjection.ServiceProviderServiceExtensions ( исходный код для DI.SPSE ), потому что IServiceProvider имеет значение null; так что я предполагаю, что мне не хватает услуги в моем списке?