powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / RoleManager очень быстро диспозится.
25 сообщений из 35, страница 1 из 2
RoleManager очень быстро диспозится.
    #39740830
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет, хочу при запуске AspCore 2.1 проекта проинициализировать некоторые данные - в частности добавить роли. Делаю это так
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
    /// <summary>
    /// Помощник по ролям
    /// </summary>
    public   class RolesHelper: IInitializer
    {
        /// <summary>
        /// Инициализируем список ролей
        /// </summary>
        private  List<string> AppRoles = new List<string>() {"Admin","ClaimManager", "EquipmentUser" };
        protected private RoleManager<IdentityRole> RoleManager { get; }

        public RolesHelper(RoleManager<IdentityRole> roleManager   )
        {
            RoleManager = roleManager;
        }

        public async void Initialize()
        {
            try
            { 
                foreach (string item in AppRoles)
                {
                    if (!await RoleManager.RoleExistsAsync(item))
                   {
                        await RoleManager.CreateAsync(new IdentityRole(item));
                   }
                }
            }
            catch (Exception ex)
            {

                throw;
            }

        }

    }



в ConfigureServices
Код: c#
1.
2.
3.
            #region DI
            services.AddTransient<IInitializer,RolesHelper>();
            #endregion



в Configure
Код: c#
1.
  serviceProvider.GetService<IInitializer>().Initialize();



Когда код доходит до RoleManager.RoleExistsAsync(item) я получаю ошибку ObjectDisposedException, то есть в конструкторе RoleManager еще не Disposed, а пока дойдет до RoleManager.RoleExistsAsync сборщик мусора его уже забирает, хотя не должен-я ведь держу на него ссылку в свойстве protected private RoleManager. Почему сборщик все равно забирает RoleManager? Спасибо
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740837
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сборщик-то тут причем? ObjectDisposedException возникает когда кто-то вызвал Dispose, а не когда сборщик прошел
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740844
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_subто есть в конструкторе RoleManager еще не Disposed, а пока дойдет до RoleManager.RoleExistsAsyncЗначит Initialize вызывается уже тогда, когда скоуп для RoleManager уже закончился. Показывай код инстанцирования и использования RolesHelper
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740859
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,
кроме кода, который я привел - больше нигде дополнительной логики по работе с RolesHelper я не использую.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
   public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            IoCContainer.Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            // Add ApplicationDbContext to DI
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(IoCContainer.Configuration["connectionStrngs:default"]));



            services.AddIdentity<ApplicationUser, IdentityRole>()
           .AddEntityFrameworkStores<ApplicationDbContext>()
           .AddDefaultTokenProviders();


            #region DI
            services.AddTransient<IInitializer,RolesHelper>();
            #endregion

            // Change password policy
            services.Configure<IdentityOptions>(options =>
            {
                // Make really weak passwords possible
                options.Password.RequireDigit = false;
                options.Password.RequiredLength = 5;
                options.Password.RequireLowercase = true;
                options.Password.RequireUppercase = false;
                options.Password.RequireNonAlphanumeric = false;

                // Make sure users have unique emails
                options.User.RequireUniqueEmail = true;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public  async void Configure(
            IApplicationBuilder app, 
            IHostingEnvironment env,
            IServiceProvider serviceProvider )
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Account}/{action=Login}");
            });

            serviceProvider.GetService<ApplicationDbContext>().Database.EnsureCreated();
            serviceProvider.GetService<IInitializer>().Initialize();
   
        }
    }



Соответственно инстанциирую и использую на строке
Код: c#
1.
 serviceProvider.GetService<IInitializer>().Initialize();
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740867
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_subв Configure
Код: c#
1.
  serviceProvider.GetService<IInitializer>().Initialize();




Не скажу на 100% что дело в этом, но для начала стоит поменять вот так:

Код: c#
1.
serviceProvider.GetService<IInitializer>().Initialize().Wait();
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740881
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_sub
Код: c#
1.
new List<string>() {"Admin","ClaimManager", "EquipmentUser" };

а ничего что в Core ушли от ролевой аутентификации к claim-based?
Т. Е. что то типа такого:
Код: c#
1.
2.
3.
4.
new list<claim>
{ 
new Claim(ClaimTypes.Role, "Aminsssss")
.... 
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740889
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделай Initialize асинхронным и вызывай через await
Естественно RoleManager умирает раньше, чем закончится выполнение Initialize, потому что ты его не ожидаешь
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740894
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProСделай Initialize асинхронным и вызывай через await
Естественно RoleManager умирает раньше, чем закончится выполнение Initialize, потому что ты его не ожидаешь
Ну да, я выше уже написал, что Wait() к вызову надо добавить.
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740896
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и вообще - наличиеvb_sub
Код: c#
1.
async void

признак того, что создаешь себе проблемы на ровном месте
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740900
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthatНу да, я выше уже написал, что Wait() к вызову надо добавить.лучше сделать как положено
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740905
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthatНу да, я выше уже написал, что Wait() к вызову надо добавить.

Ну ёмаё..
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740909
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Proлучше сделать как положено

Через await его не вызовешь, потому что для этого надо делать асинхронным сам Configure, а это, afaik, asp.net еще не умеет.
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740913
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthatЧерез await его не вызовешь, потому что для этого надо делать асинхронным сам Configure, а это, afaik, asp.net еще не умеет.посмотри в приведенный код
vb_sub
Код: c#
1.
public  async void Configure(
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740916
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Proи вообще - наличиеvb_sub
Код: c#
1.
async void

признак того, что создаешь себе проблемы на ровном месте

Изначально Initialize был Async Task
и было

Код: c#
1.
 await serviceProvider.GetService<IInitializer>().Initialize();


-ошибка аналогичная, я сначала подумал, что await как-то неправильно дожидается ход выполнения и начал раскручивать в синхронную версию, но из-за того, что у RoleManager есть только асинхронная версия RoleExistsAsync, пришлось остановиться на async void. Собственно проблема не в асинхронности- при обоих вариантах RoleManager уже задиспозен.
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740923
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123vb_sub
Код: c#
1.
new List<string>() {"Admin","ClaimManager", "EquipmentUser" };

а ничего что в Core ушли от ролевой аутентификации к claim-based?
Т. Е. что то типа такого:
Код: c#
1.
2.
3.
4.
new list<claim>
{ 
new Claim(ClaimTypes.Role, "Aminsssss")
.... 



Чем claim-based лучше?
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740925
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Значит надо создать скоуп, потому что лайвтайм RoleManager по идее Scoped
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740931
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_subЧем claim-based лучше?
1. Полная поддержка из коробки
2. Комбинирование с соц.сетями и SSO.
3. Шире чем роли, т.к. Роль это просто ключ тире значение в claim.
.... Выше константу для роли видел?
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740932
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProЗначит надо создать скоуп, потому что лайвтайм RoleManager по идее Scoped
Код: c#
1.
2.
3.
4.
			using (var serviceScope = app.ApplicationServices.CreateScope())
			{
				await serviceScope.ServiceProvider.GetService<IInitializer>().Initialize();
			}
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740933
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,
скоуп дает аналогичную ошибку.
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740934
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я пробовал с AddScoped
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740936
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пробуй CreateScope
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740937
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro
Код: c#
1.
public  async void Configure(



Оно не сработает. Configure это специальный метод, который вызывается извне, фреймворком, и тот требует, чтобы он был объявлен именно как "public void".
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740941
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthatОно не сработает.ты сам пробовал, чтобы это утверждать?
fkthatтот требуетпусть требует, надо бы знать, что async - инструкция для компилятора, а не часть сигнатуры
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740943
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
///в ConfigureServices
       services.AddTransient<IInitializer,RolesHelper>();


//в Configure
    using (var serviceScope = app.ApplicationServices.CreateScope())
            {
                await serviceScope.ServiceProvider.GetService<IInitializer>().Initialize();
            }


Все получилось, спасибо. Только странно, из-за чего так пришлось велосипедить?
...
Рейтинг: 0 / 0
RoleManager очень быстро диспозится.
    #39740946
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_sub,
Ну и самое главное, можно войти не имея роль, но имея разрешение(identity).
Например публичный раздел сайта для рекламщиков.
...
Рейтинг: 0 / 0
25 сообщений из 35, страница 1 из 2
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / RoleManager очень быстро диспозится.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]