#asp.net #hangfire
Вопрос:
Я использую hangfire в приложении, и мне необходимо выполнить аутентификацию панели мониторинга с помощью моих репозиториев. Чтобы сделать это, я должен разрешить хранилище внутри метода авторизации Hangfire, но, используя OwinContext
, я не смог этого сделать. Я решил использовать SimpleInjector для этого проекта, и, поскольку он регистрирует все во WebApiConfig
Register
время метода s, я хочу добраться до него. Недавно я использовал middleware
as MessageHandler
, и, исходя из этого, я успешно разрешил зависимость с помощью HttpRequestMessage
. Но OwinContext
я не могу добраться до него и устранить зависимость с его помощью HttpRequestMessage.GetDependencyScope()
.
Вот как Hangfire предлагает выполнить аутентификацию для Asp.net приложения в их документации;
public class MyAuthorizationFilter : IDashboardAuthorizationFilter
{
public bool Authorize(DashboardContext context)
{
// In case you need an OWIN context, use the next line, `OwinContext` class
// is the part of the `Microsoft.Owin` package.
var owinContext = new OwinContext(context.GetOwinEnvironment());
// Allow all authenticated users to see the Dashboard (potentially dangerous).
return owinContext.Authentication.User.Identity.IsAuthenticated;
}
}
Поскольку я использую Angular
на интерфейсе, это owinContext.Authentication.User
значение равно нулю. И даже если бы это было не так, я хочу только сам дотянуться до приборной панели. Так что это не решило бы мою проблему.
Как я могу разрешить свои зависимости здесь внутри Authorize
метода?
Я не могу сделать это с помощью инъекции конструктора, потому что для hangfire вы говорите UseHangfireDashboard
на Startup.cs
s Configuration
, как указано ниже;
Это мое Startup.cs
досье
private IEnumerable<IDisposable> GetHangfireServers()
{
Hangfire.GlobalConfiguration.Configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage("CONN_STR", new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true
});
yield return new BackgroundJobServer();
}
public void Configuration(IAppBuilder app)
{
app.UseHangfireAspNet(GetHangfireServers);
app.UseHangfireDashboard("/hangfire", new DashboardOptions {
Authorization = new [] {
new DashboardAuthorization()
/* explanation */
// for DI to work through constructor,
//I have to give my AuthRepository as a parameter here.
//And my AuthRepository also has many DIs so,
//it's not possible through here.
}
});
BackgroundJob.Enqueue(() => Console.WriteLine("Hello world from Hangfire!"));
}
Кстати, мой проект-это проект .Net Framework 4.7.2.
Комментарии:
1. Вы пробовали инъекцию конструктора? Сработало ли это? Каков был результат?
2. Нет, для того, чтобы сделать это, я должен отдать это от самого
Startup.cs
себя, и я, похоже, не в состоянии этого сделать.3. Почему? Когда вы не в состоянии что-то сделать, пожалуйста, четко объясните, что вам мешает.
4. @mason Я отредактировал вопрос, чтобы показать, почему, спасибо за предложение 🙂
5. Вам не нужно складывать их в один файл. В файле Startup.cs создайте экземпляр контейнера DI и зарегистрируйте свои службы. Затем вы можете передать этот контейнер в конфигурацию веб-API, в конфигурацию Hangfire и в любое другое место, где он вам понадобится.
Ответ №1:
Что касается Hangfire, вы несете ответственность за предоставление экземпляра класса, реализующего IDashboardAuthorizationFilter. Поэтому, если у этого класса есть зависимости, которые вы хотите внедрить, это будет зависеть от вас. Вероятно, лучше всего зарегистрировать этот тип и его зависимости в вашем контейнере DI, и пусть он разрешит вам экземпляр. Таким образом, он позаботится о введении всех зависимостей для вас с помощью инъекции конструктора.
Вы должны в конечном итоге получить шаблон, подобный этому, в файле Startup.cs, где вы настраиваете конвейер OWIN.
public void Configuration(IAppBuilder app)
{
var container = CreateContainerWithRegisteredServices();
var dashboardFilter = container.Resolve<IDashboardAuthorizationFilter>();
app.UseHangfireDashboard("/hangfire", new DashboardOptions {
Authorization = new [] { dashboardFilter }
});
BackgroundJob.Enqueue(() => Console.WriteLine("Hello world from Hangfire!"));
// Configure Web API, SignalR, or whatever else hangs off your OWIN pipeline.
// You can pass the container into their configure methods if necessary.
}
IContainer CreateContainerWithRegisteredServices()
{
//this method will look different depending on your chosen IoC library
var container = SomeIoCLibrary.CreateContainer();
container.Register<MyAuthorizationFilter, IDashboardAuthorizationFilter>();
//register other dependencies here
return container;
}