Search code examples
c#asp.net-coreasp.net-identity

Why don't async methods in identity services in ASP.NET Core have a parameter for CancellationToken?


My question is why async methods like userManager.FindByNameAsync(username) in identity Services in Asp.Net Core do not have a parameter for CancellationToken? I know it has a property with CancellationToken.None value and pass to Entityframework methods but it never sets a value and it`s read only and I cannot set a value for that What are the solutions for this problem? This is Identity UserManage service

When I want to override CancellationToken in My custom service which inherited from userManager

iherited


Solution

  • Short answer is by design because value cannot change. Related to the needs, custom implementation of UserManager.cs or at least specific methods needed may be a solution, if not HttpContext.RequestAborted is the only cancellation token stopping UserManager async invocations.

    Long answer, value of an immutable property won't change, the only way in can change the value is in the constructor of base/abstract class. Overwritten value of a virtual property is in the driven class same rule apply, meaning all the time there are two values, one in base one in driven. Even if property is mutable, referring from driven at base.whatever when explicitly assigned something will change base value.

    Example:

    using Xunit;
    
    namespace Tests
    {
        public class MyBase
        {
            public MyBase()
            {
            }
    
            public MyBase(int immutableInt)
            {
                ImmutableInt = immutableInt;
            }
    
            protected virtual int ImmutableInt { get; } = -1;
            protected virtual int MutableInt { get; set; } = -1;
        }
    
    
        public class MyDriven : MyBase
        {
            public MyDriven()
            {
            }
    
            public MyDriven(int value)
            {
                ImmutableInt = value;
                MutableInt = value;
            }
    
            public MyDriven(int immutableInt, int mutableInt1): base(immutableInt)
            {
                ImmutableInt = immutableInt;
                MutableInt = mutableInt1;
            }
    
    
            protected override int ImmutableInt { get; }
            protected override int MutableInt => base.MutableInt;
    
            public int ImmutableIntReadonly => ImmutableInt;
            public int BaseImmutableIntReadonly => base.ImmutableInt;
    
            public int MutableIntReadonly => MutableInt;
            public int BaseMutableIntReadonly => base.MutableInt;
    
        }
    
        public class ImmutableTests
        {
            [Fact]
            public void TestImutableOverride()
            {
                MyDriven imutable = new MyDriven(1);
                Assert.Equal(1, imutable.ImmutableIntReadonly);
                Assert.Equal(-1, imutable.BaseImmutableIntReadonly);
                Assert.Equal(1, imutable.MutableIntReadonly);
                Assert.Equal(1, imutable.BaseMutableIntReadonly);
    
    
                MyDriven imutableCtor = new MyDriven(1, 1);
                Assert.Equal(1, imutableCtor.ImmutableIntReadonly);
                Assert.Equal(1, imutableCtor.BaseImmutableIntReadonly);
                Assert.Equal(1, imutableCtor.MutableIntReadonly);
                Assert.Equal(1, imutableCtor.BaseMutableIntReadonly);
            }
        }
    
    }