0

I recently got started with the Microsoft Graph, and as part of it, OAuth. I downloaded an official sample and looking at what they are doing in the code, and there's this part I wasn't really able to understand.

public sealed class SampleAuthProvider : IAuthProvider
{
    // Properties used to get and manage an access token.
    private string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];
    private string appId = ConfigurationManager.AppSettings["ida:AppId"];
    private string appSecret = ConfigurationManager.AppSettings["ida:AppSecret"];
    private string scopes = ConfigurationManager.AppSettings["ida:GraphScopes"];
    private SessionTokenCache tokenCache { get; set; }

    private static readonly SampleAuthProvider instance = new SampleAuthProvider();
    private SampleAuthProvider() { }

    public static SampleAuthProvider Instance
    {
        get
        {
            return instance;
        }
    }
}

It looks to me that this class is instantiating itself within itself (I'm not sure what I'm saying right now myself). Is it trying to store access token temporarily...? if so what is the point of the instantiation...?

Marc LaFleur
  • 31,987
  • 4
  • 37
  • 63
  • 1
    This is s Singleton pattern. There will be only 1 instance through whole program. – Ivien Oct 10 '18 at 07:30
  • 1
    This class just get an single instance. It does not store the access token until we called the `GetUserAccessTokenAsync` method. – Keen Jin Oct 10 '18 at 08:20

2 Answers2

1

This is known as the singleton pattern.

First, note that the constructor is private. This means you can't instantiate the class yourself. How do you get an instance then? Well, there's a property called "Instance", and that property is instantiated inside the class itself, where the constructor is accessible. The Instance property is public, so you can access it, and it's static, so there's only one of it.

The idea is that there's some special logic that needs to be done when you instantiate one of these things, and that you should generally have only one instance in your app. To make sure that you follow this, the constructor has been made private so that you can't use it to create more instances, and the Instance property is there so you can get hold of one.

So, if you try this...

IAuthProvider myAuthProvider = new SampleAuthProvider();    //error!

...it won't work, because that constructor is private.

But, if you do this...

IAuthProvider myAuthProvider = SampleAuthProvider.Instance;    //ok!

...that will work just fine. Of course, you could argue that you don't need to assign it to a local variable at all, because you can always just access the static property, but it's often a good idea to do it anyway. For example, you might have a class that needs this to do its work:

public class SomeClassThatNeedsAuth
{
    public SomeClassThatNeedsAuth(IAuthProvider authProvider)
    {
        _authProvider = authProvider;
    }

    private readonly IAuthProvider _authProvider;
}

Doing it this way means that in normal usage you can do this...

var workerClass = new SomeClassThatNeedsAuth(SampleAuthProvider.Instance);

...but in tests, you can do this...

var workerClassToBeTested = new SomeClassThatNeedsAuth(new DummyAuthProviderForTests());

...and now your tests don't have to rely on the real auth provider, and you can use your dummy one to check what happens in various scenarios without having to figure out how to make the real one do those things. You can of course wire up some dependency injection to do this for you, which makes it even easier.

anaximander
  • 7,083
  • 3
  • 44
  • 62
  • Thank you for answering my question together with the intended benefits! I'll give a look at other design patterns as well! Thanks, –  Oct 11 '18 at 01:27
0

Is it trying to store access token temporarily...?

It does not store the access token until we called the GetUserAccessTokenAsync method.

TokenCache userTokenCache = new SessionTokenCache(signedInUserID, httpContext).GetMsalCacheInstance(); This code show that, the access token will be store in the SessionTokenCache

if so what is the point of the instantiation...?

This is just a single instance through whole program, just a Design Patterns

Keen Jin
  • 1,060
  • 1
  • 6
  • 8