Lecture thumbnail 0:00 / 0:00 Asynchronous invocation cannot happen everywhere.

Asynchronous invocation can happen in methods, but it cannot happen in constructors, which becomes

a bit of a problem because sometimes you want to do asynchronous initialization.

So the question is how can you actually implement this?

And the simplest way, the most direct way, maybe not the most convenient, is to use a factory or

a factory method which actually performs the asynchronous call for you.

And then you have to remember to basically make this call.

So let me show you what I mean here.

Let’s say we have a class called Foo.

Now let’s suppose that the class foo has to do something in the constructor that is asynchronous.

Maybe it needs to load a web page which is done using asynchronous API.

Now, unfortunately, what you cannot do is you cannot just make a constructor and then start doing

asynchronous calls in the constructor.

You cannot await anything in the constructor.

You cannot await, for example, something like task delay, for example.

That’s simply impossible.

And if you try to compile it well, you get an error that the await expression can only be used in a

method or a lambda marked with the async modifier.

So you have to move this code to some method which can actually handle all of this.

So the first approach you might take is to simply introduce some sort of special initialization method

for actually performing the asynchronous part of initialization.

So you might have something like public async task, or you can even make a fluent interface.

We can make it a task of foo init async.

So this is where you would put the asynchronous initialization so you can do some work here.

You can await task dot delay 1000 and then you either don’t return anything in the case if it’s like

an async void or something or what you do is you return this.

For example, if you want to make a fluent interface, but whatever you do, this makes the use of the

class rather complicated because not only do you have to invoke the constructor, so you make a new

instance of foo, but you also have to remember to call init async and await it.

If you forget this, well then obviously that’s a problem because then none of the initialization code

is actually going to fire and your object will not be initialized correctly.

So there is really no way around this.

There is no built in net mechanism to help you mitigate this.

The only thing we can do is we can use something like a factory or indeed a factory method, which would

prohibit the use of the constructor because if people can use the constructor, they can end up in an

uninitialized state, but it will allow you to have a special factory method, for example, for creating

the whole thing.

So let’s make a few modifications.

So this is probably not the best option.

Let’s comment this out, but let’s make a few modifications.

So here what you would do is you would make the constructor private.

So this is, by the way, where you would just, you know, let’s let’s just leave it blank for now.

So you’d make the constructor private so that nobody can actually instantiate the object this way.

You would also make init async private because it has to be called only internally, so we’ll make this

private as well.

But what you would do is you’d make a factory method so you’d have some sort of public static task of

foo create async.

There we go.

So this is where you would construct the object.

So you’d say var result equals dufu like so, and then you would return.

What you would return is result dot init async.

So you would perform the asynchronous initialization, you would get a task of foo as the output and

you would return that from the factory method.

So how would you use all of this?

Well, it’s rather simple.

So here you would say await.

Let me check my curly braces here.

I think the formatting might be broken somewhere.

So you would say await and then you would say foo dot, create async.

And here if you wanted to have any arguments equivalent to the constructor arguments, you would put

them in here and that’s pretty much it.

So this is how you would initialize the object.

And then of course, once you initialize the object, you would introduce a variable, let’s call it

X, for example.

So just X, not X async.

So you’d have this variable x which would actually give you the object.

So then x is let me just specify the type explicitly.

X is of type foo and that should hopefully explain why we have task of foo being returned here as well

as here.

So this is how you can quickly get at the result with asynchronous initialization just by using a factory

method and instead of a factory method you could make a fully fledged factory if that’s what you wanted

to do.

But this is a fairly simple approach to ensuring that the consumer, the client, which consumes your

APIs, only gets to initialize the object fully and does it in an asynchronous manner.

Play Play Play Stop Play Play Play Play Play Start Play