WEBVTT

00:00:00.930 --> 00:00:03.890
Okay, we're on the On .NET show.

00:00:03.890 --> 00:00:07.400
And today we've got
Immo Landworth,

00:00:08.800 --> 00:00:11.470
who is a program manager
on the .NET team.

00:00:11.470 --> 00:00:13.160
We actually work
together I think.

00:00:13.160 --> 00:00:14.180
>> Yes.
>> [LAUGH]

00:00:14.180 --> 00:00:14.764
>> [LAUGH]

00:00:14.764 --> 00:00:16.234
>> And today we're gonna do

00:00:16.234 --> 00:00:18.362
a deep dive on .NET standard 20.

00:00:18.362 --> 00:00:20.970
>> And
[INAUDIBLE] centered in general.

00:00:20.970 --> 00:00:21.520
>> Right.
>> And

00:00:21.520 --> 00:00:24.480
I think we've heard quite
a few questions about that.

00:00:24.480 --> 00:00:25.750
>> Yep.
>> Think people are excited.

00:00:25.750 --> 00:00:27.250
They think it's a good thing.

00:00:27.250 --> 00:00:30.840
But don't necessarily completely
understand it in all cases.

00:00:30.840 --> 00:00:31.660
>> Right.

00:00:31.660 --> 00:00:32.860
>> So let's do a deep dive.

00:00:32.860 --> 00:00:36.090
I think you are definitely one
of the experts on this topic.

00:00:36.090 --> 00:00:37.302
>> I better be.
>> [LAUGH] Yeah.

00:00:37.302 --> 00:00:39.243
>> Cuz I've spent two
years working on this.

00:00:39.243 --> 00:00:40.050
[LAUGH]
>> Yeah.

00:00:40.050 --> 00:00:41.740
I mean how can it take so long?

00:00:41.740 --> 00:00:43.325
>> I know right.
It seems such an easy concept.

00:00:43.325 --> 00:00:45.849
So let's start.

00:00:45.849 --> 00:00:49.030
>> I have a few slides and then
also I have tons of demos and

00:00:49.030 --> 00:00:51.230
then feel free to interrupt
me and ask questions.

00:00:51.230 --> 00:00:51.780
>> I will.

00:00:51.780 --> 00:00:54.310
Well like I said, I'm going
to provide the laugh track.

00:00:54.310 --> 00:00:54.810
>> Nice.

00:00:56.500 --> 00:00:58.289
>> It may just be me but
I don't know the answer but hey.

00:00:59.360 --> 00:01:02.300
All right, so the big question
really is why do we care

00:01:02.300 --> 00:01:03.170
about .NET standard.

00:01:03.170 --> 00:01:06.160
That's usually the first thing
that people wonder because

00:01:06.160 --> 00:01:08.740
they know .NET and
usually when they think of .NET

00:01:08.740 --> 00:01:09.970
they think of
the .NET framework.

00:01:09.970 --> 00:01:11.730
They may not call it
the .NET framework but

00:01:11.730 --> 00:01:14.430
that's effectively what
we should 15 years ago.

00:01:14.430 --> 00:01:17.550
And the world was really simple
back then because we only had

00:01:17.550 --> 00:01:19.720
one framework to worry about and

00:01:19.720 --> 00:01:22.970
you could build basically, you
know both types of back then.

00:01:22.970 --> 00:01:28.283
Like basically desktop apps and
it was apps for .NET.

00:01:28.283 --> 00:01:30.753
And of course you could
build console apps and

00:01:30.753 --> 00:01:32.710
window services and
what have you.

00:01:32.710 --> 00:01:34.610
But you were always on
this one framework.

00:01:34.610 --> 00:01:37.900
So when business logic you would
just use it on this framework

00:01:37.900 --> 00:01:39.090
based on this library BCL.

00:01:39.090 --> 00:01:41.160
>> I remember that.

00:01:41.160 --> 00:01:43.660
>> Good old days, right,
and then over the years,

00:01:43.660 --> 00:01:44.380
we added more stuff.

00:01:44.380 --> 00:01:45.720
So there's Xamarin, for example,

00:01:45.720 --> 00:01:48.870
which does the same
thing in terms of

00:01:48.870 --> 00:01:51.300
giving you a .NET platform
that is really productive.

00:01:51.300 --> 00:01:54.630
But they focus more on
the mobile devices, specifically

00:01:54.630 --> 00:01:57.890
the non-Windows ones, iOS,
OS X, and then Android.

00:01:57.890 --> 00:02:00.300
Obviously, OS X is not a mobile,
but same thing there.

00:02:00.300 --> 00:02:03.810
It's basically the idea is you
build different types of apps

00:02:03.810 --> 00:02:06.270
essentially with their
version of .NET.

00:02:06.270 --> 00:02:08.090
And they are built off of Mono.

00:02:08.090 --> 00:02:10.449
So Mono is very similar
to .NET framework, but

00:02:10.449 --> 00:02:12.180
it's not 100% identical.

00:02:12.180 --> 00:02:13.570
So when you talk
about business logic,

00:02:13.570 --> 00:02:15.330
now you have two things
to worry about, right.

00:02:15.330 --> 00:02:18.350
And then with .NET Core,
there is one more.

00:02:18.350 --> 00:02:20.460
And so we have another
mobile angle here with UWP.

00:02:20.460 --> 00:02:23.700
But then there's also the new
ASP.NET Core stuff, and

00:02:23.700 --> 00:02:26.560
there's yet
another BCL for .NET Core.

00:02:26.560 --> 00:02:28.140
And they are different
because they're

00:02:28.140 --> 00:02:29.350
different code bases, right?

00:02:29.350 --> 00:02:32.390
So when we accept PRs, we use
the accept the PRs on the .NET

00:02:32.390 --> 00:02:35.050
Core side of the house, because
that's where the party is.

00:02:35.050 --> 00:02:37.740
And then from there, report it
to the net framework or mono, or

00:02:37.740 --> 00:02:40.740
whatever other implementations
we might have in the future.

00:02:40.740 --> 00:02:41.295
And so like,

00:02:41.295 --> 00:02:45.360
re-using code becomes now this
multi-dimensional problem right?

00:02:45.360 --> 00:02:48.370
And so like we talk about these
things at the top as application

00:02:48.370 --> 00:02:50.780
models, that's the thing
you build your app with and

00:02:50.780 --> 00:02:53.860
the thing at the bottom we
just call them base libraries,

00:02:53.860 --> 00:02:54.920
general purpose stuff.

00:02:54.920 --> 00:02:55.420
>> Right.

00:02:58.100 --> 00:03:00.610
>> We like to say
it's three plus one

00:03:00.610 --> 00:03:02.780
because it's basically
three different things and

00:03:02.780 --> 00:03:06.910
the plus one is what's actually
common across all of them.

00:03:06.910 --> 00:03:10.490
You have to keep in mind which
API's you can actually share.

00:03:10.490 --> 00:03:12.826
When you want to a now write
a library you basically have to

00:03:12.826 --> 00:03:15.263
compile multiple times from
multiple [INAUDIBLE] platforms

00:03:15.263 --> 00:03:17.300
and it basically
becomes really hard.

00:03:17.300 --> 00:03:21.578
>> Right, I know when I was
using the combination of .NET

00:03:21.578 --> 00:03:24.190
Framework and .NET Core 1.x.

00:03:24.190 --> 00:03:25.920
>> Right.
>> Kind of before all of these

00:03:25.920 --> 00:03:27.350
completely landed.

00:03:27.350 --> 00:03:29.460
I was doing some file IO.

00:03:29.460 --> 00:03:30.750
I think it was a file stream and

00:03:30.750 --> 00:03:33.820
actually I was in the file
stream with stream reader and

00:03:33.820 --> 00:03:38.810
there was one important method
that I really wanted to

00:03:38.810 --> 00:03:42.290
use and I was using it
in .Net framework and

00:03:42.290 --> 00:03:46.010
then I copied the code over
to core x and it didn't work.

00:03:46.010 --> 00:03:47.730
And I was left unhappy.

00:03:49.220 --> 00:03:55.470
Fortunately, some time passed,
and then I tried to redo that

00:03:55.470 --> 00:03:59.500
same exercise with .NET Core
2.0, and that API was there.

00:03:59.500 --> 00:04:02.630
And I was happy, and
I just went on with my work.

00:04:02.630 --> 00:04:04.390
So, definitely had
that experience.

00:04:04.390 --> 00:04:06.510
>> Yeah, so that's exactly
the problem, right?

00:04:06.510 --> 00:04:09.540
And if you pull up a class
library, it's the same thing.

00:04:09.540 --> 00:04:11.990
Except it's even
more complicated.

00:04:11.990 --> 00:04:14.780
>> I guess the other thing too
is, like with that code that

00:04:14.780 --> 00:04:18.650
I brought over, I was
already using the best API.

00:04:18.650 --> 00:04:21.510
It wasn't like I thought,

00:04:21.510 --> 00:04:23.760
maybe some better way to do
this that I didn't know about.

00:04:23.760 --> 00:04:25.920
I knew I was using
the best pattern.

00:04:25.920 --> 00:04:30.020
So I was equally annoyed
because I would have to do

00:04:30.020 --> 00:04:32.900
something that I fundamentally
believe was worse.

00:04:32.900 --> 00:04:34.250
>> Yes.

00:04:34.250 --> 00:04:36.610
>> Fortunately with this new
model that's no longer the case.

00:04:36.610 --> 00:04:37.570
>> That's right.

00:04:37.570 --> 00:04:40.586
And so basically when we now
think about .NET Standard, what

00:04:40.586 --> 00:04:43.486
it actually does it basically
tries to unify is essentially

00:04:43.486 --> 00:04:46.270
that base layers who don't
have that experience anymore

00:04:46.270 --> 00:04:49.228
where Platform A decides to do
something little bit outdated

00:04:49.228 --> 00:04:51.729
and then you don't have a way
to do it the right way.

00:04:51.729 --> 00:04:54.764
And so, you can think of the new
net standard essentially as

00:04:54.764 --> 00:04:56.220
the one BCL to rule them all,

00:04:56.220 --> 00:04:58.118
I think we have said
this many times.

00:04:58.118 --> 00:05:02.120
But logically it's basically The
set of APIs that really every

00:05:02.120 --> 00:05:05.519
.NET platform should have,
because they are really

00:05:05.519 --> 00:05:08.466
foundational pieces
like I/O collections,

00:05:08.466 --> 00:05:09.976
access to the console,

00:05:09.976 --> 00:05:13.250
stuff you do basically in
lower levels libraries.

00:05:13.250 --> 00:05:15.026
And by lower level
really mean like non app

00:05:15.026 --> 00:05:16.150
specific stuff, right?

00:05:16.150 --> 00:05:17.480
Business logic comes to mind,

00:05:17.480 --> 00:05:18.920
data access layers
comes to mind.

00:05:18.920 --> 00:05:22.190
>> But
there is also a user promise.

00:05:22.190 --> 00:05:24.130
Developer promise aspect to it.

00:05:24.130 --> 00:05:25.090
>> Right.

00:05:25.090 --> 00:05:27.439
Which is basically they do-
everything you put in .NET

00:05:27.439 --> 00:05:31.450
standard will go
everywhere moving forward.

00:05:31.450 --> 00:05:32.949
And we will talk a little bit
more about versioning and

00:05:32.949 --> 00:05:33.660
how it works in general.

00:05:33.660 --> 00:05:35.494
But the idea being that
the standard itself has

00:05:35.494 --> 00:05:37.890
version numbers, because we
don't have a time machine.

00:05:37.890 --> 00:05:40.620
We can't retroactively
add an API five years ago

00:05:40.620 --> 00:05:41.730
that doesn't work.

00:05:41.730 --> 00:05:44.230
So when we add new API's as a
new version of the standard, but

00:05:44.230 --> 00:05:46.520
the expectation is that all
platforms will eventually move

00:05:46.520 --> 00:05:48.580
to the later version, they
never get stuck on the version.

00:05:48.580 --> 00:05:49.240
>> Right.

00:05:49.240 --> 00:05:50.530
>> So
you can't bifurcate essentially,

00:05:50.530 --> 00:05:53.070
it's always,
you always move forward and

00:05:53.070 --> 00:05:54.630
consistency catches
up over time.

00:05:54.630 --> 00:05:57.970
>> Well you know, I do know
someone who has a time machine.

00:05:57.970 --> 00:05:59.220
You do?

00:05:59.220 --> 00:06:03.190
>> Yeah, so, it's a great-
>> We should hire that guy.

00:06:03.190 --> 00:06:05.780
>> Yeah, actually,
it's a woman now.

00:06:05.780 --> 00:06:07.180
>> I guess that's true.

00:06:07.180 --> 00:06:08.570
What's his name again?

00:06:08.570 --> 00:06:09.670
Or her name?
[LAUGH]

00:06:09.670 --> 00:06:11.130
>> Well, it's still

00:06:11.130 --> 00:06:12.440
the same name, I think.

00:06:13.560 --> 00:06:16.190
She comes in December.

00:06:16.190 --> 00:06:17.110
>> Nice.
>> Yeah, cool.

00:06:18.920 --> 00:06:21.440
So then what's the difference
we done send it to

00:06:21.440 --> 00:06:24.270
the previous picture as
like there is only one BCL.

00:06:24.270 --> 00:06:26.790
I like to say it's not a Venn
diagram because it's only really

00:06:26.790 --> 00:06:29.310
one thing reversion
numbers hiding so,

00:06:29.310 --> 00:06:31.790
that's easier than
an overlapping

00:06:31.790 --> 00:06:34.630
diagram of multiple circles
>> Definitely.

00:06:34.630 --> 00:06:37.290
>> And then the other thing
you pointed out is, with

00:06:37.290 --> 00:06:39.600
we've added a ton more APIs, and
I have a slide on that as well,

00:06:39.600 --> 00:06:42.192
but basically we really try to
make the common dominator large.

00:06:42.192 --> 00:06:45.481
Like with portable we
just modeled what we had,

00:06:45.481 --> 00:06:47.900
which was largely sub-optimal.

00:06:47.900 --> 00:06:51.444
But now we actually went out of
our way to make sure that we put

00:06:51.444 --> 00:06:56.400
a that we think is sensible and
this one is pretty large.

00:06:56.400 --> 00:06:57.830
And we just fill in the gaps for

00:06:57.830 --> 00:06:59.610
platforms that don't
have those APIs.

00:06:59.610 --> 00:07:01.660
Rather than the other
way around.

00:07:01.660 --> 00:07:02.830
And so the customer promises and

00:07:02.830 --> 00:07:04.760
essentially you can just
target the standard.

00:07:04.760 --> 00:07:07.374
And it promises you can run
anywhere where that version of

00:07:07.374 --> 00:07:08.690
the standard is supported.

00:07:10.220 --> 00:07:11.750
>> Right.
So you probably remember in

00:07:11.750 --> 00:07:14.631
grade school learning about
lowest common denominator.

00:07:14.631 --> 00:07:15.850
>> Yes.

00:07:15.850 --> 00:07:19.620
>> I kind of think the PCL
project that we did was a bit of

00:07:19.620 --> 00:07:23.110
a lowest common
denominator project.

00:07:23.110 --> 00:07:26.859
This one, I think in all honesty
is really like a largest common

00:07:26.859 --> 00:07:28.276
denominator project,

00:07:28.276 --> 00:07:30.920
particularly with
.NET standard 2.0.

00:07:30.920 --> 00:07:31.990
Do you think that's fair?

00:07:31.990 --> 00:07:33.130
>> Yeah, I think to me,

00:07:33.130 --> 00:07:36.080
the difference is
more intentionality.

00:07:36.080 --> 00:07:37.890
PCL model is what we had.

00:07:37.890 --> 00:07:39.060
So it was an afterthought.

00:07:39.060 --> 00:07:40.532
Every platform did
whatever they want.

00:07:40.532 --> 00:07:43.062
And then we provided tooling
that had to model what

00:07:43.062 --> 00:07:43.671
was there.

00:07:43.671 --> 00:07:46.015
With standard we said,
this is what we want,

00:07:46.015 --> 00:07:48.605
now lets make sure all
the things are there, and so

00:07:48.605 --> 00:07:51.083
we maxed out what we think
was the right API set.

00:07:51.083 --> 00:07:53.903
>> Yeah one thing I sometimes
tell people that I usually get

00:07:53.903 --> 00:07:56.913
blank stares on, so great topic
to get into for this video.

00:07:56.913 --> 00:07:57.621
>> That sounds great.

00:07:57.621 --> 00:08:02.422
>> Yeah is, with PCL, all
the profiles with the awesome

00:08:02.422 --> 00:08:05.634
names were all
machine generated.

00:08:05.634 --> 00:08:10.531
So there was no human thought
involved in creating those

00:08:10.531 --> 00:08:11.580
profiles.

00:08:11.580 --> 00:08:13.189
>> That's right.

00:08:13.189 --> 00:08:15.240
>> Which sounds super bizarre.

00:08:15.240 --> 00:08:18.420
And so that's the difference
with this in that you used

00:08:18.420 --> 00:08:20.560
the word intentionality.

00:08:20.560 --> 00:08:23.580
So, there was human thought
involved in basically

00:08:23.580 --> 00:08:26.910
every single member that we
pulled into .NET standard.

00:08:28.060 --> 00:08:30.710
So, yeah means now you
have humans to blame.

00:08:30.710 --> 00:08:33.310
>> [LAUGH]
>> But I think that is a huge,

00:08:33.310 --> 00:08:34.830
huge difference.

00:08:34.830 --> 00:08:35.870
>> I think so too.

00:08:38.860 --> 00:08:39.700
So, then what is the standard?

00:08:39.700 --> 00:08:40.690
I mean that's usually the thing.

00:08:40.690 --> 00:08:42.910
It all sounds great when you
have like abstract diagrams so

00:08:42.910 --> 00:08:45.020
really what it boils down
to in Visual Studio is

00:08:45.020 --> 00:08:47.340
when you do fun new project you
have this new category here

00:08:47.340 --> 00:08:48.830
called .NET standard and

00:08:48.830 --> 00:08:51.140
it has one template in it to
cross library .NET standards.

00:08:51.140 --> 00:08:54.390
So it's a project
type you can create.

00:08:54.390 --> 00:08:56.420
So, that's the mechanical
piece to it.

00:08:56.420 --> 00:08:58.150
And the actionable piece
that you do date today.

00:08:58.150 --> 00:09:00.863
The second part of it,
it's a specification, so

00:09:00.863 --> 00:09:02.682
it's essentially a set of APIs.

00:09:02.682 --> 00:09:06.426
That we say all platforms shall
implement those APIs, so one way

00:09:06.426 --> 00:09:09.295
to think about this is you can-
>> Can I just be a jerk for

00:09:09.295 --> 00:09:09.831
a moment?

00:09:09.831 --> 00:09:11.421
>> Yeah, it comes naturally.

00:09:11.421 --> 00:09:12.263
>> Yeah, it comes naturally.

00:09:12.263 --> 00:09:13.790
Go back to the other slide.

00:09:13.790 --> 00:09:14.300
>> Yes.

00:09:14.300 --> 00:09:16.990
>> So this is just a tiny
bit of a joke, but

00:09:16.990 --> 00:09:21.780
I think people will ask this,
I'm in the .NET Standard node,

00:09:21.780 --> 00:09:23.770
I see cross library
.NET standard.

00:09:23.770 --> 00:09:27.260
Why do I see .NET
Framework 4.5.2 there?

00:09:27.260 --> 00:09:28.220
>> You mean the drop-down
at the top?

00:09:28.220 --> 00:09:30.900
>> Yeah, I just feel like that's
something to call attention to.

00:09:30.900 --> 00:09:33.960
>> Yeah, so this is basically
the end result of my very first

00:09:33.960 --> 00:09:35.850
slide when I said, we used to
have the .NET framework and

00:09:35.850 --> 00:09:37.210
the world was good.

00:09:37.210 --> 00:09:38.820
And so we say,
it would be nice if you could

00:09:38.820 --> 00:09:41.370
choose the version number
before you create the template.

00:09:41.370 --> 00:09:44.930
And later on, maybe add in more
.NET flavors like [INAUDIBLE] at

00:09:44.930 --> 00:09:46.710
some point as well.

00:09:46.710 --> 00:09:49.350
Like this drop down lost a lot
of it's value, probably should

00:09:49.350 --> 00:09:52.180
be at the very bottom and
you'd select the name.

00:09:52.180 --> 00:09:54.889
And it should be sensitive to
it's directional template but

00:09:54.889 --> 00:09:56.694
the dialog is just
not representing that

00:09:56.694 --> 00:09:57.768
unfortunately today.

00:09:57.768 --> 00:10:01.207
>> Do you think that so
that future makes sense to me.

00:10:01.207 --> 00:10:03.095
>> Yes.
>> Do you think that will ever

00:10:03.095 --> 00:10:03.637
happen?

00:10:03.637 --> 00:10:04.985
I sure hope so.

00:10:04.985 --> 00:10:05.986
>> Yeah.
>> I've said it before on

00:10:05.986 --> 00:10:08.303
Twitter, I think this whole
dialogue needs an overhaul.

00:10:08.303 --> 00:10:10.154
>> Yeah.
>> There's a little bit too many

00:10:10.154 --> 00:10:12.706
choices and names that are not
necessarily reflective

00:10:12.706 --> 00:10:14.600
of how you think about
the world today.

00:10:14.600 --> 00:10:15.470
>> Yeah, okay.

00:10:16.530 --> 00:10:17.700
>> Yeah, so that's that.

00:10:17.700 --> 00:10:19.380
So then we think about
the specification part.

00:10:19.380 --> 00:10:21.420
So if you think of the standard
as a specification,

00:10:22.660 --> 00:10:23.920
a good analogy is HTML.

00:10:23.920 --> 00:10:26.162
So the HTML is a spec and
then there is the browser.

00:10:26.162 --> 00:10:27.673
So we implement those spec.

00:10:27.673 --> 00:10:30.788
There's Edge, Chrome and each
one of those browsers basically

00:10:30.788 --> 00:10:32.756
snap to a different
version of the spec.

00:10:32.756 --> 00:10:34.603
But in the same way it
happens to .NET standards.

00:10:34.603 --> 00:10:36.603
So the standard is
essentially the HTML spec and

00:10:36.603 --> 00:10:39.303
then the browser's equivalent
is basically the concrete .NET

00:10:39.303 --> 00:10:41.703
platforms implemented like
.NET Family, .NET Core,

00:10:41.703 --> 00:10:42.516
Xamarin, Unity.

00:10:42.516 --> 00:10:46.310
And whatever we might
create in the future.

00:10:46.310 --> 00:10:50.380
So that's a really good
mental picture to have.

00:10:50.380 --> 00:10:51.858
So, like I said earlier,

00:10:51.858 --> 00:10:55.500
with 2.0 we're really trying
to adding many more APIs back.

00:10:55.500 --> 00:10:59.143
In fact, we added about 20,000
APIs, compared to .NET Standard

00:10:59.143 --> 00:11:03.130
1.x or 1.6, which was the
highest version into 1x series.

00:11:03.130 --> 00:11:05.693
And the way we arrived at that
number was we basically said,

00:11:05.693 --> 00:11:07.598
well, what is the maximum
we can envision?

00:11:07.598 --> 00:11:10.628
And the maximum that we can
envision is take .NET framework

00:11:10.628 --> 00:11:13.058
and take Xamarin, and
mold the intersection.

00:11:13.058 --> 00:11:15.148
Because that's essentially
a good proxy for

00:11:15.148 --> 00:11:17.073
APIs that could be
cross-platform, but

00:11:17.073 --> 00:11:19.937
they're still very similar to
what the .NET framework has.

00:11:19.937 --> 00:11:21.587
And then we also added a few
APIs that were only in

00:11:21.587 --> 00:11:23.280
.NET framework that
Xamarin didn't have, and

00:11:23.280 --> 00:11:24.367
asked them to implement them.

00:11:24.367 --> 00:11:27.825
So we don't have
a Franken-set essentially.

00:11:27.825 --> 00:11:31.508
>> So essentially if we just go
with the simple scenario that

00:11:31.508 --> 00:11:36.189
you mentioned, the intersection
of .NET framework, say, 4.7 and

00:11:36.189 --> 00:11:39.413
Mono latest, that
intersection that wasn't yet

00:11:39.413 --> 00:11:42.350
in .NET Core was
around 20,000 APIs.

00:11:42.350 --> 00:11:43.683
>> Correct, so most of our work-
>> That's huge.

00:11:43.683 --> 00:11:45.610
>> Was not revving the spec.

00:11:45.610 --> 00:11:48.990
Most of the work was then
implementing this back on Core.

00:11:48.990 --> 00:11:51.229
Framework was by construction
already supported.

00:11:51.229 --> 00:11:53.333
Xamarin had to add
very few APIs.

00:11:53.333 --> 00:11:55.859
I think it's probably less than
100 APIs we asked Xamarin to

00:11:55.859 --> 00:11:56.390
implement.

00:11:57.660 --> 00:12:00.240
So yeah, we had 20,000 APIs
we had to add to Core,

00:12:00.240 --> 00:12:02.479
so that was the bulk
of our work.

00:12:04.810 --> 00:12:06.592
>> I'm writing them
to UWP as well.

00:12:06.592 --> 00:12:07.677
>> Correct,

00:12:07.677 --> 00:12:10.390
UWP, on the first slide,
it's kind of lumped up with .NET

00:12:10.390 --> 00:12:12.305
Core because they're kinda
both from the same code base.

00:12:12.305 --> 00:12:14.064
>> Mm-hm.
>> So they don't get it for

00:12:14.064 --> 00:12:17.523
free unfortunately, because
UWP has a different runtime

00:12:17.523 --> 00:12:19.931
environment than
normal Windows does.

00:12:19.931 --> 00:12:22.888
So there is work that happens
to add the OS to support app

00:12:22.888 --> 00:12:24.380
container and all of that.

00:12:24.380 --> 00:12:27.298
But yeah, they will also
get the same API, Surface.

00:12:27.298 --> 00:12:28.311
We'll ship later this year.

00:12:28.311 --> 00:12:30.420
I don't think they announced
the date yet, right?

00:12:30.420 --> 00:12:32.003
It will come.

00:12:32.003 --> 00:12:35.307
The second thing is, I guess,
another interesting tidbit that

00:12:35.307 --> 00:12:38.119
when you try to create a set
of libraries with one axis,

00:12:38.119 --> 00:12:41.299
the problem you usually run into
is first of all, when you copy

00:12:41.299 --> 00:12:44.550
your own code, there's tons
of APIs that you miss out.

00:12:44.550 --> 00:12:45.570
But that's in your control.

00:12:45.570 --> 00:12:47.260
You can refactor your code.

00:12:47.260 --> 00:12:49.099
It may be a ton of work,
but you can do it.

00:12:49.099 --> 00:12:51.233
Usually where the story ends,
though,

00:12:51.233 --> 00:12:54.245
is you that have dependencies
on third party libraries,

00:12:54.245 --> 00:12:55.952
that somebody else gave to you.

00:12:55.952 --> 00:12:59.142
Think X unit for
example, or JSON.net, or

00:12:59.142 --> 00:13:01.222
whatever you actually use.

00:13:01.222 --> 00:13:03.574
And the majority of the
libraries in Nuget today are not

00:13:03.574 --> 00:13:04.707
targeting the Standard.

00:13:04.707 --> 00:13:06.417
They're still targeting
.NET framework,

00:13:06.417 --> 00:13:08.487
because that's the thing
that's around for so long.

00:13:08.487 --> 00:13:09.715
And so the question we have is,

00:13:09.715 --> 00:13:11.190
okay, how do we
make this smoother?

00:13:11.190 --> 00:13:13.592
How do we make it easier for
people to port-to-port?

00:13:13.592 --> 00:13:16.262
So [INAUDIBLE] what we call
a compatibility shim or

00:13:16.262 --> 00:13:19.585
compat mode, which basically
allows you to reference Nuget

00:13:19.585 --> 00:13:22.980
packages that really only
work on .NET framework today.

00:13:22.980 --> 00:13:25.727
And we tried to go out of our
way make that work on .NET

00:13:25.727 --> 00:13:26.355
Standard.

00:13:26.355 --> 00:13:27.323
And by extension,

00:13:27.323 --> 00:13:30.113
any platform that implements
.NET Standard 2.0.

00:13:30.113 --> 00:13:32.585
And there's a demo l have which
probably explains a little

00:13:32.585 --> 00:13:34.766
better but the idea here
it's a best effort thing.

00:13:34.766 --> 00:13:37.037
So we don't know what
the library does.

00:13:37.037 --> 00:13:39.123
And if it uses Win Forms for
example,

00:13:39.123 --> 00:13:41.896
it will not work on a command
on Linux obviously.

00:13:41.896 --> 00:13:46.328
But the majority of libraries we
found on Nuget about 70% are API

00:13:46.328 --> 00:13:49.111
comparable what we
have in .NET 2.0.

00:13:49.111 --> 00:13:51.985
So In practice, most of
the time, when you upgrade and

00:13:51.985 --> 00:13:54.736
you just reference an existing
framework package,

00:13:54.736 --> 00:13:57.200
it will probably just work fine.

00:13:57.200 --> 00:13:59.970
>> Right, so I get the caveat
emptor nature of this.

00:13:59.970 --> 00:14:01.166
>> Yep.
>> As a user,

00:14:01.166 --> 00:14:06.352
it will be awesome if I
could say, I'm currently

00:14:06.352 --> 00:14:11.888
using blah Nuget package It
shouldn't really be the case

00:14:11.888 --> 00:14:16.983
that I have to go explore
that completely by myself.

00:14:16.983 --> 00:14:19.107
If it's in this 70% bucket,

00:14:19.107 --> 00:14:22.578
are there any lists anywhere
that I could go look at?

00:14:22.578 --> 00:14:24.361
>> You mean like lists of
new Nuget packages that we

00:14:24.361 --> 00:14:25.550
know will work?

00:14:25.550 --> 00:14:26.485
>> Yeah.

00:14:26.485 --> 00:14:28.006
>> No, I don't think
we have a list today.

00:14:28.006 --> 00:14:29.814
That's actually
a good suggestion.

00:14:29.814 --> 00:14:30.821
We should probably have a list.

00:14:30.821 --> 00:14:31.801
>> Yeah.

00:14:31.801 --> 00:14:34.441
>> The other thing you wanna do
is you wanna reach out to Nuget

00:14:34.441 --> 00:14:34.991
authors and

00:14:34.991 --> 00:14:37.930
actively encourage them to
support .NET Standard natively.

00:14:37.930 --> 00:14:39.070
Especially when they're

00:14:39.070 --> 00:14:41.000
already de facto
compatible of it anyway.

00:14:41.000 --> 00:14:43.670
It just takes an explicit step
on the package to say, yes,

00:14:43.670 --> 00:14:45.490
I support it on .NET 2.0.

00:14:45.490 --> 00:14:48.132
So that is also more intentional
on the package author side.

00:14:48.132 --> 00:14:50.669
>> Well,
if we were super strategic,

00:14:50.669 --> 00:14:54.222
it seems like we'd say,
these are the 100

00:14:54.222 --> 00:14:58.301
most popular libraries that
only have .NET framework.

00:14:58.301 --> 00:14:59.800
Dependencies and
reach out to them.

00:14:59.800 --> 00:15:01.187
>> Yes.
>> Has your team thought

00:15:01.187 --> 00:15:01.879
about that?

00:15:01.879 --> 00:15:04.745
>> Yes, I mean, you should know
he's my boss, so what he's

00:15:04.745 --> 00:15:07.450
basically telling me right
now is I should go do this.

00:15:07.450 --> 00:15:08.580
>> Get it on tape.

00:15:08.580 --> 00:15:09.940
>> Get it on tape,
it's public now.

00:15:11.840 --> 00:15:15.410
We actually did this, we came

00:15:15.410 --> 00:15:17.730
to that number by basically
doing what you just said.

00:15:17.730 --> 00:15:21.060
We did a whole analysis
on NuGet packages.

00:15:21.060 --> 00:15:23.050
There is actually a video where
I walk you through the deck of

00:15:23.050 --> 00:15:24.570
all the findings we have.

00:15:24.570 --> 00:15:25.210
What we haven’t done,

00:15:25.210 --> 00:15:27.090
because it is more of
a quantitative effort.

00:15:27.090 --> 00:15:28.670
We haven’t really
drilled into this.

00:15:28.670 --> 00:15:31.870
Actually we just talked to them,
but there are a few high profile

00:15:31.870 --> 00:15:34.025
packages that we actually ended
up submitting PRs directly to-

00:15:34.025 --> 00:15:34.640
>> [CROSSTALK}

00:15:34.640 --> 00:15:35.660
That's even better actually.

00:15:35.660 --> 00:15:38.400
>> To actually fix it and
add bonus internatively.

00:15:38.400 --> 00:15:40.550
>> And were those PRs accepted?

00:15:40.550 --> 00:15:41.540
>> Most of the time, yes.

00:15:41.540 --> 00:15:44.720
Some of the time it was
different than the 1X the Delta

00:15:44.720 --> 00:15:47.930
and the Cobra was pretty large,
and people didn't feel like

00:15:47.930 --> 00:15:51.790
that seems like a lot of
disruption in my co-pays.

00:15:51.790 --> 00:15:54.490
With 2.0 it's mostly, you add
another folder to your NuGet

00:15:54.490 --> 00:15:56.800
package, and
that's pretty much it.

00:15:58.230 --> 00:15:59.570
Depending on how you
build the project,

00:15:59.570 --> 00:16:02.400
you may end up adding a T-gram
to the project too, so

00:16:02.400 --> 00:16:04.840
you'll get the compiled
time check as well.

00:16:04.840 --> 00:16:08.680
But it's a very minimal filter
on 2.0 for the most part.

00:16:08.680 --> 00:16:10.810
So, 2.0 changes are mostly
accepted, I think [INAUDIBLE].

00:16:10.810 --> 00:16:13.970
>> Right, so that's a much
easier conversation

00:16:13.970 --> 00:16:14.497
with the maintainer.

00:16:16.670 --> 00:16:18.950
>> All right,
enough of the slides,

00:16:18.950 --> 00:16:21.260
let's actually look at a demo.

00:16:21.260 --> 00:16:22.470
So, what I have here is,

00:16:22.470 --> 00:16:25.380
unfortunately the font
is not amazing, but

00:16:25.380 --> 00:16:27.660
you can hopefully see it on
the video screen quite well.

00:16:28.790 --> 00:16:30.647
So, basically, what we have
here is Northwind, and

00:16:30.647 --> 00:16:32.096
anybody who does development for

00:16:32.096 --> 00:16:33.920
a long time is
aware of Northwind.

00:16:33.920 --> 00:16:35.180
And so,
I have a very simple app here,

00:16:35.180 --> 00:16:41.460
it's the Windforms app, and you
can clearly tell I'm a designer,

00:16:41.460 --> 00:16:44.720
because when I change the size
here the button sticks

00:16:44.720 --> 00:16:47.120
at the bottom right corner, so
I did a really good job there.

00:16:47.120 --> 00:16:50.470
But basically all I did here,
is I load some of the data from

00:16:50.470 --> 00:16:54.170
Northwind and look for
people that are retired by now,

00:16:54.170 --> 00:16:56.580
so you can tell
[LAUGH] this data is.

00:16:56.580 --> 00:16:57.866
The key thing here is,

00:16:57.866 --> 00:17:00.550
that my actual database
right now is not SQL.

00:17:00.550 --> 00:17:03.820
It's actually using Dataset,
which was our in map

00:17:03.820 --> 00:17:06.140
representation of the databases
in the one x days.

00:17:06.140 --> 00:17:07.770
>> Can you maybe zoom
that in just a tad?

00:17:07.770 --> 00:17:10.167
>> I can, I think.

00:17:14.228 --> 00:17:15.944
Maybe 150 is probably
even better.

00:17:15.944 --> 00:17:17.160
Here we go.

00:17:17.160 --> 00:17:18.770
And so, what you can see
here is basically, all I do,

00:17:18.770 --> 00:17:23.210
is I just create a data set,
load it hardcore from file,

00:17:23.210 --> 00:17:24.660
with like a hard coded path.

00:17:24.660 --> 00:17:26.810
Like, really great
filament story on my side.

00:17:26.810 --> 00:17:27.980
I just look for
people that are retired.

00:17:27.980 --> 00:17:29.640
Right?

00:17:29.640 --> 00:17:32.950
Birthday, plus 65 years, which
is the general retirement age.

00:17:32.950 --> 00:17:35.084
I think an age,
is probably more like, 40.

00:17:35.084 --> 00:17:36.374
>> [LAUGH] Yeah.

00:17:36.374 --> 00:17:37.750
>> I've heard US is more like,
120.

00:17:37.750 --> 00:17:38.810
>> Yeah [LAUGH].

00:17:38.810 --> 00:17:40.010
>> So, parameterize that.

00:17:40.010 --> 00:17:42.890
But basically here I just search
for that and just display that.

00:17:44.150 --> 00:17:45.730
So, why does it
with .NET Standard?

00:17:45.730 --> 00:17:48.260
So, they just have one of those
APIS that we considered legacy

00:17:48.260 --> 00:17:50.370
and basically we
moved from the one x.

00:17:50.370 --> 00:17:53.850
But it turns out people may not
be in love with the dataset,

00:17:53.850 --> 00:17:56.658
but the reality is you're even
less in love with having to

00:17:56.658 --> 00:17:58.800
re-factor a to get rid of it.

00:17:58.800 --> 00:18:00.610
>> Definitely, and we did here.

00:18:00.610 --> 00:18:01.530
Quite a lot of feedback.

00:18:01.530 --> 00:18:04.230
>> Yeah, and there's a bunch of
stuff that actually is useful.

00:18:04.230 --> 00:18:06.115
So, what I will do now,
is I will create a new project.

00:18:06.115 --> 00:18:09.926
I will go to .NET center
categories we've talked about,

00:18:09.926 --> 00:18:13.191
select on the center, and
then we'll call this,

00:18:13.191 --> 00:18:15.230
let's say, Northwind data.

00:18:17.925 --> 00:18:19.770
Deta two already created their
project apparently before.

00:18:20.800 --> 00:18:22.370
>> Been there, done that.

00:18:22.370 --> 00:18:24.050
>> Exactly, so.

00:18:24.050 --> 00:18:25.270
And then,
I just delete the class one,

00:18:25.270 --> 00:18:29.050
and then I just take my
data access logic now, and

00:18:29.050 --> 00:18:32.590
just move it over
to my new project.

00:18:32.590 --> 00:18:33.910
>> Nice.

00:18:33.910 --> 00:18:35.580
>> So, now,
I have it in here, and

00:18:35.580 --> 00:18:37.690
you can tell there's
no squiggles.

00:18:37.690 --> 00:18:39.080
Everything just works fine.

00:18:40.200 --> 00:18:42.384
If you actually go to
the project properties,

00:18:42.384 --> 00:18:44.624
you find that we target
.NET Standard 2.0,

00:18:44.624 --> 00:18:46.550
cuz that's what we default to.

00:18:46.550 --> 00:18:47.450
>> Yeah.

00:18:47.450 --> 00:18:50.130
>> If I switch it to one x,
you will get tons of squiggles.

00:18:51.780 --> 00:18:53.210
So, now,
we have a modern code base,

00:18:53.210 --> 00:18:55.050
not quite,
it modernizes a bit more,

00:18:55.050 --> 00:19:00.700
there's all these explicit
types, so let me just do this.

00:19:00.700 --> 00:19:02.200
Now, I see var everywhere.

00:19:02.200 --> 00:19:05.030
It's awesome, I know,
it's a modern code base clearly.

00:19:05.030 --> 00:19:06.030
>> Definitely.
>> [LAUGH].

00:19:06.030 --> 00:19:08.180
>> That's the one that
Casey doesn't like, right?

00:19:08.180 --> 00:19:10.570
>> Exactly, the nevar people?

00:19:10.570 --> 00:19:11.870
>> Yeah.

00:19:11.870 --> 00:19:14.830
>> So, now, we have this, but
now, let's actually extend this

00:19:14.830 --> 00:19:19.540
and say, I'm not keen on
this hard-coded lookup here.

00:19:19.540 --> 00:19:22.500
So, what I've done
about ten years ago,

00:19:22.500 --> 00:19:25.200
I think, I wrote a SQL engine
that can actually allow you

00:19:25.200 --> 00:19:28.150
to do the same thing I do here
right now with C#, but with SQL.

00:19:29.570 --> 00:19:31.870
So, let's actually
add my library here.

00:19:31.870 --> 00:19:34.140
So, I just go to
my NuGet packages.

00:19:34.140 --> 00:19:37.870
I search for
my library on NuGet.

00:19:37.870 --> 00:19:39.180
Find my library.

00:19:39.180 --> 00:19:42.469
You can tell here uploaded 2012.

00:19:42.469 --> 00:19:44.220
>> Is that still when
you had spare time?

00:19:44.220 --> 00:19:45.410
>> That's when I
still had spare time,

00:19:45.410 --> 00:19:48.180
because before I worked for you,
now I don't have spare time.

00:19:48.180 --> 00:19:50.630
>> Well,
you also traveled at some point.

00:19:50.630 --> 00:19:51.180
>> That's true too.

00:19:52.640 --> 00:19:53.560
So, install this thing.

00:19:56.200 --> 00:20:00.008
It succeeded, however,
when we now build.

00:20:00.008 --> 00:20:03.987
We look at the error list
we see a warning here.

00:20:03.987 --> 00:20:05.399
And the warning says,

00:20:05.399 --> 00:20:08.902
[INAUDIBLE] was restored
using .NET framework 461.

00:20:08.902 --> 00:20:11.750
Instead of the target framework
of .NET standard version 2.0.

00:20:11.750 --> 00:20:13.170
So, why is that.

00:20:13.170 --> 00:20:16.784
Well, if we just go to
[INAUDIBLE] .org and we just

00:20:16.784 --> 00:20:21.466
search for my package here, and
we just download the package.

00:20:24.572 --> 00:20:26.803
When we open this in package
explorer it's very obvious

00:20:26.803 --> 00:20:28.260
what the problem is.

00:20:28.260 --> 00:20:30.800
If I look in the lip
folder from 2012, I think,

00:20:30.800 --> 00:20:34.241
I originally awarded that
thing in 2005-2006 time frame.

00:20:34.241 --> 00:20:36.694
So, that was when .NET
2.0 was all the hype, so

00:20:36.694 --> 00:20:38.300
that's what I'm targeting.

00:20:38.300 --> 00:20:41.628
So, that there's nothing PCL,
nothing .NET standard just

00:20:41.628 --> 00:20:43.747
a good old .NET framework and
binary.

00:20:43.747 --> 00:20:45.460
>> You might wanna give
a quick shout out for

00:20:45.460 --> 00:20:46.582
what this app is for.

00:20:46.582 --> 00:20:48.478
>> Yeah, this is,
you get Package Explorer,

00:20:48.478 --> 00:20:50.380
it's actually in
the Windows Store.

00:20:50.380 --> 00:20:52.730
If you just go to the store
you can search it there.

00:20:52.730 --> 00:20:54.421
It allows you to open
new get packages and

00:20:54.421 --> 00:20:57.008
browse them visually, I mean,
they're just zip files, but

00:20:57.008 --> 00:20:59.740
that's a bit nicer too, because
you see the metadata here.

00:20:59.740 --> 00:21:01.860
>> I definitely use this
app multiple times a week,

00:21:01.860 --> 00:21:02.910
you probably use it every day.

00:21:02.910 --> 00:21:04.543
>> Yeah.
Every time I do demos at

00:21:04.543 --> 00:21:05.276
least [LAUGH].

00:21:05.276 --> 00:21:08.580
>> [LAUGH]
>> So, we have that and

00:21:08.580 --> 00:21:11.480
now what we can is,
I can now reuse my library.

00:21:11.480 --> 00:21:15.680
So, let me get rid of all
my hardware logic here.

00:21:15.680 --> 00:21:21.987
If I could find a way to
use the mouse [LAUGH].

00:21:21.987 --> 00:21:26.770
Maybe not,
maybe it will do this.

00:21:28.200 --> 00:21:32.490
And then, we just delete
all of this stuff here, and

00:21:32.490 --> 00:21:34.850
then, instead drop
in some knowledge.

00:21:34.850 --> 00:21:39.060
So, that's using library
enough to add using at this

00:21:39.060 --> 00:21:41.960
point, basically all it does is
just create the data context

00:21:41.960 --> 00:21:45.110
that holds on to the dataset
respective of your connection,

00:21:45.110 --> 00:21:46.210
does a SQL query.

00:21:47.450 --> 00:21:50.225
Uses some link magic to render
the result and some for

00:21:50.225 --> 00:21:51.495
running the app again.

00:21:54.263 --> 00:21:55.585
That doesn't build any more.

00:21:58.718 --> 00:22:00.398
Because I have to add
a reference library of

00:22:00.398 --> 00:22:01.085
course as well.

00:22:01.085 --> 00:22:03.030
>> [LAUGH]
>> Just creating the new library

00:22:03.030 --> 00:22:04.380
doesn't quite help.

00:22:04.380 --> 00:22:05.730
>> Also have to reference
it I've been told.

00:22:08.680 --> 00:22:09.540
We write this again.

00:22:09.540 --> 00:22:14.580
This is the same
thing as before.

00:22:14.580 --> 00:22:15.080
So, now,

00:22:15.080 --> 00:22:18.760
you have basically moved your
staff to down standard to all.

00:22:18.760 --> 00:22:19.990
So, this could be
no reference for

00:22:19.990 --> 00:22:21.230
many library,
we could reference it for

00:22:21.230 --> 00:22:24.700
me it has been a core we could
reference it from examine app,

00:22:24.700 --> 00:22:26.595
but what you see here
is this is warning.

00:22:26.595 --> 00:22:28.384
You can also [INAUDIBLE]
this warning it's solution

00:22:28.384 --> 00:22:30.420
explorer that shows
it's the same thing.

00:22:30.420 --> 00:22:31.500
So, the intent here is,

00:22:31.500 --> 00:22:33.780
we let you know if this is
going through the compaction.

00:22:33.780 --> 00:22:35.380
We don't know what this
library does, right?

00:22:35.380 --> 00:22:38.330
It may use WinForms,
it may use APIs we don't have.

00:22:38.330 --> 00:22:40.170
So, the intention here
is you test your app,

00:22:40.170 --> 00:22:41.910
you convince yourself
that it's working fine.

00:22:41.910 --> 00:22:45.030
And then, you effectively
just suppress the warning.

00:22:45.030 --> 00:22:48.840
As you see here, like this is,
one number here,

00:22:48.840 --> 00:22:50.990
which is NU one, seven, or
one that's a warning number for

00:22:50.990 --> 00:22:51.630
the compaction.

00:22:51.630 --> 00:22:54.540
So, all you have to do
is to select enter here,

00:22:54.540 --> 00:22:58.670
and then you just enter the
warning number here, hit Enter,

00:22:58.670 --> 00:23:01.940
and save, and now, you can see
the one disappears from solution

00:23:01.940 --> 00:23:07.120
explorer, and it also disappears
from here the rebuild.

00:23:07.120 --> 00:23:10.090
>> So,
one thing I was playing with

00:23:10.090 --> 00:23:12.750
recently was either this
weekend, or last week.

00:23:12.750 --> 00:23:17.090
I was playing with
the warnings errors.

00:23:17.090 --> 00:23:18.660
>> Yes.
>> Dialog.

00:23:18.660 --> 00:23:22.260
Can you talk a little bit about
what built, so we know that

00:23:22.260 --> 00:23:27.630
a number of folks operate
with a warnings as errors.

00:23:27.630 --> 00:23:29.300
>> Right.
>> So, in this kind of model

00:23:30.460 --> 00:23:33.050
is that incapatable with
that kind of system, or

00:23:33.050 --> 00:23:34.710
can you speak to that?

00:23:34.710 --> 00:23:36.200
>> Yes, so the idea here is,
I think, so

00:23:36.200 --> 00:23:41.040
what they have done now with
the latest version of VS is they

00:23:41.040 --> 00:23:44.453
kind of bridge the gap between
warnings from the and warnings

00:23:44.453 --> 00:23:49.330
from so they're all in the same
UI and the same experience.

00:23:49.330 --> 00:23:52.170
For example, here, you see
specific warnings already

00:23:52.170 --> 00:23:54.670
suppressed, specific
warnings already treated.

00:23:54.670 --> 00:23:59.200
For example, and so, you can you
know change those settings and

00:23:59.200 --> 00:24:01.940
you can, for example, say, I
want the NU1701 to be an error,

00:24:01.940 --> 00:24:04.920
so I don't want to ever go
through the compaction.

00:24:04.920 --> 00:24:08.240
The other thing is you wanna
suppress the warnings.

00:24:08.240 --> 00:24:10.120
>> And where would you
specify that if you wanted

00:24:10.120 --> 00:24:11.169
to have a-
>> You would specify

00:24:11.169 --> 00:24:11.876
the right here [INAUDIBLE].

00:24:11.876 --> 00:24:12.422
>> Okay.

00:24:12.422 --> 00:24:14.518
>> So, I would basically say,
treat one of those arrows,

00:24:14.518 --> 00:24:15.198
I would say, NU.

00:24:15.198 --> 00:24:15.770
>> Okay.

00:24:15.770 --> 00:24:17.070
>> That now it becomes an error,
right.

00:24:17.070 --> 00:24:18.100
>> Okay, I see you.

00:24:18.100 --> 00:24:20.709
>> Yeah, the thing is if you
look at the project file it's

00:24:20.709 --> 00:24:22.582
average per system
with the same NU1,

00:24:22.582 --> 00:24:25.230
and property that
compile at one for.

00:24:25.230 --> 00:24:27.110
So, it's a very
simple workflow now.

00:24:27.110 --> 00:24:29.560
You can just edit there, and
then it will just travel.

00:24:29.560 --> 00:24:30.216
>> Right, so for

00:24:30.216 --> 00:24:32.352
people that have those
kind of build systems,

00:24:32.352 --> 00:24:34.450
they should play just
like everything else.

00:24:34.450 --> 00:24:35.650
>> Yes.

00:24:35.650 --> 00:24:37.940
And the idea generally is they
give you suppressor warning.

00:24:37.940 --> 00:24:40.709
It's addressed, so even if you
have warnings [INAUDIBLE] on,

00:24:40.709 --> 00:24:43.372
like a suppress warning is no
longer causing the boat to fail

00:24:43.372 --> 00:24:44.453
essentially, right?

00:24:44.453 --> 00:24:46.944
>> Got it.

00:24:46.944 --> 00:24:50.350
>> All right,
that was that demo.

00:24:51.510 --> 00:24:56.461
Let's go back to the deck.

00:24:56.461 --> 00:24:59.420
So, the other question
usually is version numbers.

00:24:59.420 --> 00:25:00.971
>> Right.
>> There's multiple versions

00:25:00.971 --> 00:25:03.800
of the standard, and then the
question is, what should you.

00:25:03.800 --> 00:25:06.487
How should you think about the
version numbers and how you're

00:25:06.487 --> 00:25:08.611
able to make a decision
of what you wanna target.

00:25:08.611 --> 00:25:15.930
So I've written some HTML,
which I probably should public.

00:25:15.930 --> 00:25:18.130
It's actually on GitHub, you can
actually get it from there but

00:25:18.130 --> 00:25:19.830
I don't have a link for
that yet.

00:25:19.830 --> 00:25:22.710
But basically what you see here
is this table that seems to

00:25:22.710 --> 00:25:25.260
confuse everybody all the time.

00:25:25.260 --> 00:25:27.160
The table is actually not
that hard once you know how

00:25:27.160 --> 00:25:29.590
to read it, but
it's not obvious.

00:25:29.590 --> 00:25:31.048
So what you see here
is at the very top,

00:25:31.048 --> 00:25:32.790
you see the version
numbers of the standard.

00:25:33.890 --> 00:25:37.168
So you can see like
from 1.0 to 2.0,

00:25:37.168 --> 00:25:40.363
what kind of version
numbers do we have?

00:25:40.363 --> 00:25:42.620
And then what you see
at the vertical axis,

00:25:42.620 --> 00:25:45.396
eventually all the .NET
implementations we have.

00:25:45.396 --> 00:25:47.744
So for instance here,
you can see, right now,

00:25:47.744 --> 00:25:49.819
we have selected
.NET Standard 1.0.

00:25:49.819 --> 00:25:52.475
And what you see here in green
is essentially all the .NET

00:25:52.475 --> 00:25:54.191
implementations you can run on,
and

00:25:54.191 --> 00:25:56.920
what the minimum version
numbers that you need to have.

00:25:56.920 --> 00:26:00.448
So for example, if I want
to run .NET Standard 1.0,

00:26:00.448 --> 00:26:02.325
I wanna target .NET 1.0,

00:26:02.325 --> 00:26:05.567
that means I run a .NET
Core since version 1.0.

00:26:05.567 --> 00:26:08.941
I can run on framework
since version number 4.5.

00:26:08.941 --> 00:26:11.634
>> Which means you just can't
support something before that.

00:26:11.634 --> 00:26:12.277
>> Correct.

00:26:12.277 --> 00:26:13.139
>> Like 4.0.

00:26:13.139 --> 00:26:15.943
>> Yes, so 4.0,
we don't run on for instance.

00:26:15.943 --> 00:26:19.498
The other thing you see here is
you see also by the shape here,

00:26:19.498 --> 00:26:23.510
that the .NET Core doesn't
actually directly implement 1.0.

00:26:23.510 --> 00:26:25.715
It actually implements 1.6.

00:26:25.715 --> 00:26:28.776
Which means I could now target
a higher version number and

00:26:28.776 --> 00:26:30.507
still run in .NET Core 1.0.

00:26:30.507 --> 00:26:32.677
So for example,
now when we target 1.1,

00:26:32.677 --> 00:26:35.620
what you see is that all of
this stuff becomes unavailable.

00:26:35.620 --> 00:26:38.967
So for example, I no longer want
a Windows Silverlight which

00:26:38.967 --> 00:26:41.724
hopefully nobody cares
about anymore with UWP but

00:26:41.724 --> 00:26:43.771
that's how table
basically works.

00:26:43.771 --> 00:26:46.725
And then when I go up even
further, if we just toggle you

00:26:46.725 --> 00:26:49.599
see essential this red trails
of stuff you don't wanna run on.

00:26:49.599 --> 00:26:51.608
And now you can see for example,

00:26:51.608 --> 00:26:56.014
now I need .NET Framework 4.6 if
I need to run .NET Center 1.3.

00:26:57.770 --> 00:27:00.603
That's basically how to read
the table, then at the very top,

00:27:00.603 --> 00:27:03.168
we have this blue bar up here
which is kinda like a proxy for

00:27:03.168 --> 00:27:04.412
the number of APIs we have.

00:27:04.412 --> 00:27:08.646
So as I'm going back to see the
SUMJUM between 1.0 and 1.1 and

00:27:08.646 --> 00:27:12.509
then between 1.1 and 1.2,
there is only a minor jump.

00:27:12.509 --> 00:27:16.037
And then, once we reach 2.0, we
see this massive spike where we

00:27:16.037 --> 00:27:18.692
have over 20,000 APIs,
this whole thing.

00:27:18.692 --> 00:27:22.532
The numbers here are not all up
to date, but the .NET Framework

00:27:22.532 --> 00:27:25.604
one is, so when you want
to target .NET Centere 2.0,

00:27:25.604 --> 00:27:28.676
you basically have to run
.NET Framework 461 and up,

00:27:28.676 --> 00:27:31.122
you don't run on 45 or
46, for example.

00:27:31.122 --> 00:27:33.260
That's essentially how
to read this table.

00:27:33.260 --> 00:27:34.415
Does that make sense to you?

00:27:34.415 --> 00:27:35.106
>> Mm-hm.

00:27:38.442 --> 00:27:41.682
I see, so shouldn't this column,

00:27:41.682 --> 00:27:46.220
this cell, just say 2.0,
.NET Core 2.0?

00:27:46.220 --> 00:27:47.964
>> Yeah, it should say 2.0 here,

00:27:47.964 --> 00:27:50.201
I forgot what the version
numbers here are.

00:27:50.201 --> 00:27:51.692
>> Yeah, but
we could fill that out, right?

00:27:51.692 --> 00:27:52.970
>> We can fill this out,

00:27:52.970 --> 00:27:56.250
there's an up-to-date
version if you go to our FAQ.

00:27:56.250 --> 00:27:58.725
There's an actual versions
table that we have here,

00:27:58.725 --> 00:28:00.650
that's the same that
we have in the docs.

00:28:00.650 --> 00:28:01.384
>> Okay, so that's up to date.

00:28:01.384 --> 00:28:03.310
>> And so you see the actual
version numbers here.

00:28:03.310 --> 00:28:06.952
I just haven't done it in
the HTMLified version of that.

00:28:06.952 --> 00:28:08.805
>> Okay.

00:28:08.805 --> 00:28:09.820
>> But yeah,
that's the same thing.

00:28:11.300 --> 00:28:13.405
So then the next
question often is, okay,

00:28:13.405 --> 00:28:14.752
how do you decide, right?

00:28:14.752 --> 00:28:16.501
And basically, it's a tradeoff.

00:28:16.501 --> 00:28:19.009
You have to decide between
the higher the version of

00:28:19.009 --> 00:28:21.720
the Standard is,
the more APIs you have.

00:28:21.720 --> 00:28:23.625
The lower the version
of the Standard is,

00:28:23.625 --> 00:28:26.347
the more reach you have, cuz
the more platform support that

00:28:26.347 --> 00:28:27.883
particular version [INAUDIBLE].

00:28:27.883 --> 00:28:30.583
Which is kinda intuitive but
it's still worth pointing out

00:28:30.583 --> 00:28:32.473
because people get
confused about that.

00:28:32.473 --> 00:28:34.591
[INAUDIBLE] this is
because this is a spec,

00:28:34.591 --> 00:28:37.730
like a version number
doesn't go out of support.

00:28:37.730 --> 00:28:38.305
>> Right.

00:28:38.305 --> 00:28:40.625
>> Because, it's basically just
the number of APIs you can

00:28:40.625 --> 00:28:41.710
access, essentially.

00:28:41.710 --> 00:28:43.304
And so, generally speaking,

00:28:43.304 --> 00:28:45.572
even though that they
have shipped 2.0,

00:28:45.572 --> 00:28:49.970
you should not feel guilty for
targeting 1.6, 1.4, or 1.0 even.

00:28:49.970 --> 00:28:52.132
Because if you can target 1.0,
by all means,

00:28:52.132 --> 00:28:53.356
you should target 1.0.

00:28:53.356 --> 00:28:56.459
You should only bump the version
number when you need more APIs.

00:28:58.270 --> 00:28:59.582
Implementations, on
the other side,

00:28:59.582 --> 00:29:00.902
they have the support policy,
right?

00:29:00.902 --> 00:29:04.359
And so for example, we may
decide that say .NET Core 1.0 is

00:29:04.359 --> 00:29:08.100
out of support eventually, and
you have to be on 1.1 or 2.0.

00:29:08.100 --> 00:29:10.316
And that just means you cannot
target a higher version of

00:29:10.316 --> 00:29:11.918
the Standard as well,
but you can always

00:29:11.918 --> 00:29:14.350
target the lower version
in order to get more reach.

00:29:14.350 --> 00:29:18.593
>> Yeah, you're basically saying
the .NET implementation versions

00:29:18.593 --> 00:29:21.737
and their support policies
have no relationship to

00:29:21.737 --> 00:29:23.650
the .NET Standard versions.

00:29:23.650 --> 00:29:25.060
>> Correct.
>> We intend to support these

00:29:25.060 --> 00:29:26.630
.NET Standard versions forever.

00:29:26.630 --> 00:29:29.658
>> Yes.
>> There's no reason for

00:29:29.658 --> 00:29:32.420
us to deprecate them.

00:29:32.420 --> 00:29:34.443
Yeah, we have no plans
of ever doing that.

00:29:34.443 --> 00:29:36.481
>> And there's also no
breaking changes, right,

00:29:36.481 --> 00:29:39.167
like the version numbers are all
monolithically increasing and

00:29:39.167 --> 00:29:41.830
you just get more APIs whenever
we move APIs from here.

00:29:41.830 --> 00:29:42.660
>> Right.

00:29:42.660 --> 00:29:43.790
>> So that makes it possible.

00:29:43.790 --> 00:29:46.478
>> Well,
not only do we not remove APIs,

00:29:46.478 --> 00:29:49.254
right, I guess that's
what you said.

00:29:49.254 --> 00:29:52.611
Yeah, and we never go back and
either add or remove APIs from

00:29:52.611 --> 00:29:53.811
a given version-
>> Correct.

00:29:53.811 --> 00:29:54.333
>> We've already shipped.

00:29:54.333 --> 00:29:55.410
Then it's immutable.

00:29:55.410 --> 00:29:59.865
>> Yes, so
it's a very simple model.

00:29:59.865 --> 00:30:03.416
So target the lowest version
you can get away with.

00:30:03.416 --> 00:30:07.404
Then, the other thing we
should point out is for

00:30:07.404 --> 00:30:12.588
people that are used to portable
class libraries, if you go to

00:30:12.588 --> 00:30:18.190
Windows C#, there is this thing
called Class Library Portable.

00:30:19.310 --> 00:30:20.766
And if you read
the text closely,

00:30:20.766 --> 00:30:22.840
you'll see it now
says Legacy Portable.

00:30:22.840 --> 00:30:25.900
So, we basically try to
tell people stop using

00:30:25.900 --> 00:30:27.490
portable class libraries.

00:30:27.490 --> 00:30:29.560
And in the text, we also say
this has been deprecated.

00:30:29.560 --> 00:30:31.863
You should use Class Library
.NET Standard instead.

00:30:31.863 --> 00:30:34.870
So .NET Standard is
the spiritual successor of

00:30:34.870 --> 00:30:36.380
portable class libraries.

00:30:36.380 --> 00:30:37.940
But it's a much
better tooling story,

00:30:37.940 --> 00:30:40.490
partially because we have
much more API surface.

00:30:40.490 --> 00:30:41.029
And secondly,

00:30:41.029 --> 00:30:43.145
because you can still reference
.NET framework binaries,

00:30:43.145 --> 00:30:43.691
which is huge.

00:30:43.691 --> 00:30:45.692
Because usually the biggest
thing with portable,

00:30:45.692 --> 00:30:47.606
that you could only
reference other portables.

00:30:47.606 --> 00:30:48.881
You could never
reference anything else.

00:30:48.881 --> 00:30:50.106
>> Right.

00:30:50.106 --> 00:30:53.104
>> And so
that really gets you unblocked.

00:30:53.104 --> 00:30:53.737
>> Yeah, so

00:30:53.737 --> 00:30:58.027
I think there should be very few
scenarios where PCL was better.

00:30:58.027 --> 00:31:00.073
>> Right.

00:31:00.073 --> 00:31:03.790
>> It's a 95%
better kinda thing.

00:31:03.790 --> 00:31:05.150
>> Yeah, I like to think
it's always better.

00:31:05.150 --> 00:31:07.670
It's just that some platforms
don't wanna support it.

00:31:07.670 --> 00:31:08.690
They no longer support it.

00:31:08.690 --> 00:31:10.777
But .NET Standard ultimately
support it [INAUDIBLE] so you're

00:31:10.777 --> 00:31:12.290
really not losing anything-
>> Right.

00:31:12.290 --> 00:31:12.900
>> Realistically.

00:31:14.010 --> 00:31:16.010
So you should just move
to the standard and

00:31:16.010 --> 00:31:18.225
that's generally an upgrade.

00:31:18.225 --> 00:31:22.567
That's I think what we have
to say about portable.

00:31:22.567 --> 00:31:25.220
The other thing that often
comes up is multi-targeting.

00:31:25.220 --> 00:31:28.100
So usually what ends
up happening is people

00:31:28.100 --> 00:31:31.170
at some point run into APIs that
don't exist in the standard.

00:31:32.310 --> 00:31:35.890
So what I have here is I have
a solution with four projects.

00:31:35.890 --> 00:31:37.713
So I can just run
it really quickly.

00:31:40.992 --> 00:31:43.864
Yeah, before we get an error
message from the UWP app,

00:31:43.864 --> 00:31:45.680
let me just deploy
this guy first.

00:31:45.680 --> 00:31:48.980
>> Yes, another one of my
favorite error messages.

00:31:51.390 --> 00:31:53.220
>> And now when I run it,
I have two apps.

00:31:55.390 --> 00:31:57.300
I can see I've had
this open before in

00:31:57.300 --> 00:31:58.380
a larger screen resolution.

00:31:58.380 --> 00:31:59.718
And so
they both do the same things.

00:31:59.718 --> 00:32:01.150
I have a WinForms app and
UWP app and

00:32:01.150 --> 00:32:02.345
they both do the same thing.

00:32:02.345 --> 00:32:05.432
They just show you the
longitude/latitude where you're

00:32:05.432 --> 00:32:08.330
located on the Earth by using
the geolocation APIs from

00:32:08.330 --> 00:32:09.800
the operating system.

00:32:09.800 --> 00:32:12.900
>> So, if you had run that app
yesterday, we could have said

00:32:12.900 --> 00:32:16.207
whether you're currently
experiencing an eclipse [LAUGH].

00:32:16.207 --> 00:32:18.575
>> Yes, we could have.

00:32:18.575 --> 00:32:20.267
>> Why didn't you
think about that?

00:32:20.267 --> 00:32:23.750
>> I don't know,
it didn't occur to me.

00:32:23.750 --> 00:32:25.450
So what I have now is
I have two libraries.

00:32:26.680 --> 00:32:32.050
Cuz I wanna share, the public
can access the GPS subsystem.

00:32:33.430 --> 00:32:35.355
So let's first look
at the .NET Framework

00:32:35.355 --> 00:32:36.537
implementation of that.

00:32:36.537 --> 00:32:40.503
And effectively, what you have
here is you basically use

00:32:40.503 --> 00:32:42.660
System.Device.Location.

00:32:42.660 --> 00:32:44.520
And you have to do
this little dance,

00:32:44.520 --> 00:32:47.700
because the first time you call
it, it may not be initialized,

00:32:47.700 --> 00:32:49.442
so you do this
little thingy here.

00:32:49.442 --> 00:32:52.356
And because it takes a while,
I have an Async version of that,

00:32:52.356 --> 00:32:53.766
so I run it on a worker thread.

00:32:53.766 --> 00:32:56.274
But essentially what I return
to you is just a tuple of

00:32:56.274 --> 00:32:58.050
longitude/latitude, right?

00:32:58.050 --> 00:32:58.813
GetCoordinates.

00:32:58.813 --> 00:33:01.128
Reasonably simple.

00:33:01.128 --> 00:33:02.826
>> A task of tuple.

00:33:02.826 --> 00:33:03.453
>> Yes.

00:33:03.453 --> 00:33:04.710
Cuz it's an Async API.

00:33:04.710 --> 00:33:06.582
And then I do the same
thing on the UWP side,

00:33:06.582 --> 00:33:08.043
except now I use different APIs.

00:33:08.043 --> 00:33:09.500
Now I use the Windows TAPIs.

00:33:09.500 --> 00:33:11.848
So you see I use
Windows.Device.Geolocations and

00:33:11.848 --> 00:33:13.713
this API's already
asynchronified, so

00:33:13.713 --> 00:33:16.071
I don't have to do like
a worker thread or anything.

00:33:16.071 --> 00:33:18.807
I can just return this guy,
I just await it and

00:33:18.807 --> 00:33:20.040
return this thing.

00:33:20.040 --> 00:33:22.930
And then I'm done with this.

00:33:22.930 --> 00:33:24.080
The reason I put this
in library is so

00:33:24.080 --> 00:33:26.230
I can reuse this across
all my WinForms network,

00:33:26.230 --> 00:33:27.560
across all my UWP apps, right?

00:33:27.560 --> 00:33:29.280
But the problem is then
I have two libraries.

00:33:29.280 --> 00:33:32.570
I have one for .NET Framework,
and I have one for UWP.

00:33:32.570 --> 00:33:34.990
So now we look at
the references here.

00:33:34.990 --> 00:33:36.017
I have to know which
one to reference.

00:33:36.017 --> 00:33:38.786
The UWP one references the UWP
version and then the .NET Core

00:33:38.786 --> 00:33:41.444
version references the .NET
Core version, I’m sorry,

00:33:41.444 --> 00:33:42.870
.NET Framework version.

00:33:42.870 --> 00:33:45.790
>> Yeah, I guess one of the
things you're doing here is, and

00:33:45.790 --> 00:33:47.231
maybe this is too deep dive.

00:33:47.231 --> 00:33:48.670
>> [LAUGH]
>> But-

00:33:48.670 --> 00:33:50.339
>> It's a deep dive day.

00:33:50.339 --> 00:33:55.230
>> In this particular case,
if the type that you were using

00:33:55.230 --> 00:33:57.300
that you got from the operating
system was a .NET type,

00:33:57.300 --> 00:34:00.590
you could have actually just
returned that position and

00:34:00.590 --> 00:34:02.540
not pulled the lat/long
out of it.

00:34:02.540 --> 00:34:05.196
>> Correct.
>> I think what you're doing is

00:34:05.196 --> 00:34:10.689
you're basically converting
the Win RT representation and

00:34:10.689 --> 00:34:14.038
type into something
more agnostic.

00:34:14.038 --> 00:34:14.639
>> Correct.

00:34:14.639 --> 00:34:16.054
>> And that is why you
have to await it and

00:34:16.054 --> 00:34:17.659
convert it to just
these two presumably-

00:34:17.659 --> 00:34:18.796
>> Right.

00:34:18.796 --> 00:34:19.991
>> Two doubles.

00:34:19.991 --> 00:34:20.891
>> That's right.

00:34:20.891 --> 00:34:21.602
>> Yeah.

00:34:21.602 --> 00:34:22.432
>> So-
>> And

00:34:22.432 --> 00:34:24.938
that's what makes the two
sides compatible.

00:34:24.938 --> 00:34:25.863
>> Yes.

00:34:25.863 --> 00:34:26.551
Well, that's the goal.

00:34:26.551 --> 00:34:27.125
>> Yeah.

00:34:27.125 --> 00:34:28.434
>> Look at this part up here.

00:34:28.434 --> 00:34:33.903
Gps name space, GpsLocation,
GetCoordinates tuple.

00:34:33.903 --> 00:34:36.784
That actually looks exactly the
same between the Win RT version

00:34:36.784 --> 00:34:38.368
and the .NET Framework version.

00:34:38.368 --> 00:34:40.300
And as you said,
it's not an accident.

00:34:40.300 --> 00:34:41.400
I did this deliberately.

00:34:41.400 --> 00:34:42.140
>> Right.

00:34:42.140 --> 00:34:44.959
>> So because now I can
use my magic wand and

00:34:44.959 --> 00:34:48.731
just switch to another branch
where I did this work.

00:34:48.731 --> 00:34:51.610
Cuz you don't wanna see me
fighting with my nonexisting

00:34:51.610 --> 00:34:53.420
mouse, I should say.

00:34:53.420 --> 00:34:56.712
Now I have a single
project called Gps.

00:34:56.712 --> 00:34:59.909
I have a single file
called now GpsLocation.

00:34:59.909 --> 00:35:01.987
And now you see instead
of having two libraries,

00:35:01.987 --> 00:35:03.161
you just have one library.

00:35:03.161 --> 00:35:04.747
And you just have some
ifdefs in the code base.

00:35:04.747 --> 00:35:08.113
And so what [INAUDIBLE] seen now
here is in this little drop down

00:35:08.113 --> 00:35:10.480
here and
you see there is three entries.

00:35:10.480 --> 00:35:13.000
There is .NET framework,
.NET standard and WWP.

00:35:14.490 --> 00:35:19.652
And if I added
the project here Normally

00:35:19.652 --> 00:35:22.266
it says target framework,
a singular and then it

00:35:22.266 --> 00:35:25.860
says whatever you're targeting,
.NET Core, .NET Centered.

00:35:25.860 --> 00:35:27.020
And I just made
this approval and

00:35:27.020 --> 00:35:30.280
it just now targeted the
standard for framework and WWP.

00:35:30.280 --> 00:35:33.460
>> Okay, can you do that with
all [INAUDIBLE] properties?

00:35:33.460 --> 00:35:34.470
>> No, unfortunately not.

00:35:34.470 --> 00:35:35.270
>> Okay, just checking.

00:35:35.270 --> 00:35:37.320
>> But, what you can do now
is because the project is not

00:35:37.320 --> 00:35:39.700
effectively compiled of times.

00:35:39.700 --> 00:35:41.880
And so what I can do now is
I can say I wanna have this

00:35:41.880 --> 00:35:45.410
reference, this NuGet package,
for all my three compilations.

00:35:45.410 --> 00:35:46.520
>> Right.
>> And I can say,

00:35:46.520 --> 00:35:49.040
when you're targeting framework
I wanna do this extra reference

00:35:49.040 --> 00:35:51.930
where add the reference
to System.Device.

00:35:51.930 --> 00:35:53.430
So you can do whatever
you want in MSBuild,

00:35:53.430 --> 00:35:54.370
using these expressions.

00:35:54.370 --> 00:35:57.880
You can basically now say,
if the target framework is 461,

00:35:57.880 --> 00:35:58.740
then I do this.

00:35:58.740 --> 00:36:00.030
Otherwise, I do that.

00:36:00.030 --> 00:36:02.760
>> Where's the closing
project tag?

00:36:02.760 --> 00:36:03.520
>> It's very much at

00:36:03.520 --> 00:36:05.530
the end because there's still
some ugly stuff I have to do.

00:36:05.530 --> 00:36:07.870
>> Oops, I asked a bad question.

00:36:07.870 --> 00:36:09.600
>> No,
you asked a right question.

00:36:09.600 --> 00:36:12.163
But logically,
that's what you have to do.

00:36:12.163 --> 00:36:12.920
>> I see.

00:36:12.920 --> 00:36:15.180
And so now what I have here now
is I have basically one method

00:36:15.180 --> 00:36:17.200
and I can just if this thing.

00:36:17.200 --> 00:36:20.090
What's interesting now is I
also target .Net standard,

00:36:20.090 --> 00:36:21.950
which I haven't done before.

00:36:21.950 --> 00:36:24.550
So what ends up happening now
is I have an implementation for

00:36:24.550 --> 00:36:28.520
this standard, and that is
not very useful supported.

00:36:28.520 --> 00:36:31.730
But what I can do now is I can-
>> So is this a little bit like,

00:36:31.730 --> 00:36:36.000
this basically like the bait and
switch pattern?

00:36:36.000 --> 00:36:37.190
Yes, it's exactly what it is.

00:36:37.190 --> 00:36:38.110
So let's.
>> Okay.

00:36:38.110 --> 00:36:40.230
>> So let's first start
by saying you know,

00:36:40.230 --> 00:36:42.080
let's produce new
the package all of this, so

00:36:42.080 --> 00:36:46.940
you just go here say package,
then we get package and bills.

00:36:46.940 --> 00:36:49.240
It's also new features we have.

00:36:49.240 --> 00:36:51.330
>> It's the 20
that's nearly 2017.

00:36:51.330 --> 00:36:54.290
>> Yes,
I believe that's already in 51.

00:36:54.290 --> 00:36:55.680
>> Yeah.

00:36:55.680 --> 00:36:59.290
Now when I build this guy,
I just go to the Output folder.

00:36:59.290 --> 00:37:01.710
First of all, you see that
there is three folders for

00:37:01.710 --> 00:37:03.820
all the different we target.

00:37:03.820 --> 00:37:06.370
>> I feel like we're gonna use
NuGetPackageExplorer again.

00:37:06.370 --> 00:37:08.710
>> Exactly, but
it's also one package, and

00:37:08.710 --> 00:37:11.380
one package, not three.

00:37:11.380 --> 00:37:12.780
>> So three folders?

00:37:12.780 --> 00:37:14.860
>> There's three folders and
then within you get NuGet,

00:37:14.860 --> 00:37:16.630
you get also three folders.

00:37:16.630 --> 00:37:18.350
With the three binaries
that we just produced, so

00:37:18.350 --> 00:37:21.926
we basically did one pass of
the, created the version, on for

00:37:21.926 --> 00:37:24.450
the WP version, and
one for the version.

00:37:24.450 --> 00:37:26.150
So, you have three
different binaries that

00:37:26.150 --> 00:37:27.750
are all packaged up.

00:37:27.750 --> 00:37:30.270
The consumer of this package
now, doesn't have to know that

00:37:30.270 --> 00:37:32.140
they have to do something
different for platform A and

00:37:32.140 --> 00:37:33.890
platform B,
I basically abstract this away.

00:37:35.940 --> 00:37:36.510
>> Nice.

00:37:36.510 --> 00:37:37.860
>> Now, you might say, well, but

00:37:37.860 --> 00:37:39.860
hold on, if I reference
this from anything else,

00:37:39.860 --> 00:37:43.360
I just exploded runtime,
that doesn't seem very useful.

00:37:43.360 --> 00:37:46.370
But it still is because I
can still do this, right?

00:37:46.370 --> 00:37:49.670
I can do public bool
isSupported, right?

00:37:51.580 --> 00:37:53.340
And now I can do the same
thing I do here.

00:37:53.340 --> 00:37:58.793
I just, instead of exploding,
I basically do this,

00:37:58.793 --> 00:38:03.652
where I just say,
if .Net framework, or UWP.

00:38:03.652 --> 00:38:04.876
>> Mm.

00:38:04.876 --> 00:38:07.120
>> I can just say return True.

00:38:10.820 --> 00:38:15.290
Else, I can say return false.

00:38:15.290 --> 00:38:17.100
>> Nice.
>> So now my caller doesn't

00:38:17.100 --> 00:38:18.730
have to know which
platforms I've supported.

00:38:18.730 --> 00:38:20.420
My caller can just
say can I access, and

00:38:20.420 --> 00:38:23.200
it probably should
be static because

00:38:23.200 --> 00:38:25.800
that's where this is
coming from, city class.

00:38:25.800 --> 00:38:28.350
Another caller can check up
front, so I imagine you do

00:38:28.350 --> 00:38:31.200
a Twitter client, right, and the
Twitter client wants to tag your

00:38:31.200 --> 00:38:32.690
tweets with the geo location.

00:38:32.690 --> 00:38:33.650
>> Right, of course.

00:38:33.650 --> 00:38:36.400
>> And clearly,
if you can't access the device,

00:38:36.400 --> 00:38:37.140
nothing bad happens.

00:38:37.140 --> 00:38:40.442
You just lose a minor feature,
and your stuff, but

00:38:40.442 --> 00:38:41.711
your app could continue to work.

00:38:41.711 --> 00:38:43.880
So the intention is that
the callers will notice that GPS

00:38:43.880 --> 00:38:47.520
location is supported, if so
forget coordinates and

00:38:47.520 --> 00:38:49.650
then the callers responsible for
dialing the codes correctly but

00:38:49.650 --> 00:38:50.290
the nice thing is,

00:38:50.290 --> 00:38:52.880
the caller doesn't have
to know which platforms.

00:38:52.880 --> 00:38:53.480
>> Right.
>> So

00:38:53.480 --> 00:38:55.630
you can extract it basically for
everybody.

00:38:55.630 --> 00:38:58.555
>> Right, so
have you shared projects before.

00:38:58.555 --> 00:38:59.105
>> Yes.

00:38:59.105 --> 00:39:02.045
>> This seems like
exactly the same thing so

00:39:02.045 --> 00:39:04.925
what's different with your
.net standard approach versus

00:39:04.925 --> 00:39:06.685
the shared projects
one that I use.

00:39:06.685 --> 00:39:09.085
>> Yes so the shared projects
approach is logically the same,

00:39:09.085 --> 00:39:11.385
you basically have one project
that holds all the source files

00:39:11.385 --> 00:39:12.145
you want to share.

00:39:12.145 --> 00:39:14.185
>> And looks very similar,
the code looks the same.

00:39:14.185 --> 00:39:17.445
>> Exactly and you have
basically for every target yet

00:39:17.445 --> 00:39:18.815
another project.

00:39:18.815 --> 00:39:20.795
So in ours case you would
have four projects.

00:39:20.795 --> 00:39:21.635
>> I see.
>> You'd have one for

00:39:21.635 --> 00:39:22.610
the standard.

00:39:22.610 --> 00:39:27.050
One for ewp, one for .Net
framework, one shared project.

00:39:27.050 --> 00:39:29.950
>> I see cuz the shared project
is almost like a virtual

00:39:29.950 --> 00:39:33.120
project, it actually
doesn't build any assets

00:39:33.120 --> 00:39:34.200
that's really the difference.

00:39:34.200 --> 00:39:36.260
>> Right it just link into
the other projects, right?

00:39:36.260 --> 00:39:40.100
>> Right so it's this convenient
layer if you will, okay.

00:39:40.100 --> 00:39:41.430
>> Yes that will have
you maintain like

00:39:41.430 --> 00:39:43.520
manual links 200
different source files.

00:39:43.520 --> 00:39:44.450
You put them all in one part and

00:39:44.450 --> 00:39:46.680
they all gonna be in
facility link from there.

00:39:46.680 --> 00:39:48.549
But now you have four projects,
but

00:39:48.549 --> 00:39:51.289
you also don't have a NuGet
package out of it yet, so

00:39:51.289 --> 00:39:54.531
you also have to provide a NuGet
package and new spec [INAUDIBLE]

00:39:54.531 --> 00:39:55.674
by hand [CROSSTALK]
>> And

00:39:55.674 --> 00:39:58.977
then you couldn't build a single
NuGet package, well, yeah,

00:39:58.977 --> 00:40:00.393
I guess that by hand piece.

00:40:00.393 --> 00:40:02.483
>> You would basically have
a [INAUDIBLE] once all

00:40:02.483 --> 00:40:04.848
projects are built,
you just copy the binaries and

00:40:04.848 --> 00:40:06.984
the binaries [INAUDIBLE]
>> You wouldn't give this nice

00:40:06.984 --> 00:40:08.149
build in an [INAUDIBLE] Feature.

00:40:08.149 --> 00:40:09.356
>> That's right.

00:40:09.356 --> 00:40:13.890
>> Right, so this is a big step
forward for that scenario.

00:40:13.890 --> 00:40:14.770
>> Right.
So the nice thing here

00:40:14.770 --> 00:40:17.340
with our advice channel is,
if you need to multi-target,

00:40:17.340 --> 00:40:22.070
you should always have it
alternate standard target, and

00:40:22.070 --> 00:40:24.820
then divert number you
choose there is a function

00:40:24.820 --> 00:40:27.615
of essentially what API
service do you need to expose.

00:40:27.615 --> 00:40:29.500
>> [INAUDIBLE] function
of the implementation.

00:40:29.500 --> 00:40:32.850
It's about which types can you
use in your public surface area

00:40:32.850 --> 00:40:34.760
to bridge the platform
differences, right.

00:40:34.760 --> 00:40:38.970
>> Right, and that's analagous
to .NET standard versioning.

00:40:38.970 --> 00:40:39.480
>> Correct.

00:40:39.480 --> 00:40:40.120
>> Yeah.
>> Yes.

00:40:40.120 --> 00:40:40.690
>> Yeah.

00:40:40.690 --> 00:40:41.870
>> Very much so, and so

00:40:41.870 --> 00:40:43.730
you just pick the lowest
one you get away with,

00:40:44.880 --> 00:40:47.650
easiest way to tell is just
>> Lower the version number

00:40:47.650 --> 00:40:48.800
office stops compiling and

00:40:48.800 --> 00:40:50.530
then use the previous one
that used to compile and

00:40:50.530 --> 00:40:51.400
that's the minimum thing.

00:40:51.400 --> 00:40:55.954
>> Right now if you did this
though you might be able to have

00:40:55.954 --> 00:40:59.718
slow increase of the .NET
standard asset but

00:40:59.718 --> 00:41:04.572
the NuGet packet version would
basically increment every

00:41:04.572 --> 00:41:08.929
time you had to make a bug fix
in any one of the platform

00:41:08.929 --> 00:41:11.428
specific implementations.

00:41:11.428 --> 00:41:12.810
>> That's right.

00:41:12.810 --> 00:41:15.582
And so this is basically
a mechanism for you to bridge

00:41:15.582 --> 00:41:18.228
platform differences and
are feeling confined to

00:41:18.228 --> 00:41:21.126
the API service of .NET center
itself and still shield

00:41:21.126 --> 00:41:24.770
your consumers from having to
think about multiple platforms.

00:41:24.770 --> 00:41:28.010
So that's basically the open
endedness of the .NET center.

00:41:28.010 --> 00:41:32.370
>> So I feel like we should
just, I know this somewhat.

00:41:32.370 --> 00:41:33.660
Obvious to you.

00:41:33.660 --> 00:41:35.240
But I think we
should just talk for

00:41:35.240 --> 00:41:39.110
like 60 seconds on these
preprocessor directives so

00:41:39.110 --> 00:41:42.920
that people grasp what
they do and when they run.

00:41:42.920 --> 00:41:45.400
>> Yes so what ends up happening
here, as I said before,

00:41:45.400 --> 00:41:49.190
this project compiles multiple
times and then the compiler is

00:41:49.190 --> 00:41:53.890
basically invoked for the same
court base three times, right?

00:41:53.890 --> 00:41:57.735
But it's also passed different
pre-processor symbols and

00:41:57.735 --> 00:42:01.199
they are basically implied
from the name of the TFM, so

00:42:01.199 --> 00:42:03.774
it's just think of
the TFM you see here.

00:42:06.055 --> 00:42:08.480
If you just go-
>> So it's kind of a convention.

00:42:08.480 --> 00:42:11.770
>> Yeah, it actually is
exactly a convention,

00:42:11.770 --> 00:42:13.660
the only thing is
a bit odd is UWP.

00:42:13.660 --> 00:42:15.670
But all the other ones are
following the same thing where

00:42:15.670 --> 00:42:17.860
basically they
are just true upward.

00:42:17.860 --> 00:42:20.550
And then essentially we replace
the dot with an underscore so

00:42:20.550 --> 00:42:22.210
it'd make it a legal identifier.

00:42:22.210 --> 00:42:22.840
>> Makes sense.
>> So

00:42:22.840 --> 00:42:24.890
you know exactly what
they are here now.

00:42:24.890 --> 00:42:26.204
The nice thing here is,

00:42:26.204 --> 00:42:29.357
in the editor, it basically
shows me all the context, so

00:42:29.357 --> 00:42:31.870
what I see now is that
I'm compiling for UWP.

00:42:31.870 --> 00:42:34.350
That this code path is active.

00:42:34.350 --> 00:42:36.570
And that this code
path is active.

00:42:36.570 --> 00:42:38.120
And that these other
ones are grayed out.

00:42:38.120 --> 00:42:39.600
So the other one's essentially

00:42:39.600 --> 00:42:42.170
considered not part
of your source code.

00:42:42.170 --> 00:42:44.605
If I now switch to, let's say,

00:42:44.605 --> 00:42:48.590
461 this is still active
because you said or but

00:42:48.590 --> 00:42:51.010
now this code is being compiled,
and not that code.

00:42:51.010 --> 00:42:52.650
>> So you get good visual cues.

00:42:52.650 --> 00:42:54.680
>> You get very much like a
visual representation of what's

00:42:54.680 --> 00:42:55.560
going on, that's right.

00:42:55.560 --> 00:42:57.090
>> Right but just to really
drive the point home,

00:42:57.090 --> 00:42:59.720
can you explain the difference
between the pound if and

00:42:59.720 --> 00:43:00.760
the regular if?

00:43:00.760 --> 00:43:03.130
>> Yeah so the difference
here is that this is

00:43:03.130 --> 00:43:04.410
>> This if statement here is

00:43:04.410 --> 00:43:06.110
available at compile time,
right?

00:43:06.110 --> 00:43:08.410
So when the compiler runs,
it evaluates this thing and

00:43:08.410 --> 00:43:11.650
says great,
I need to consider this code.

00:43:11.650 --> 00:43:15.453
And so basically the end result
says if you would have only written

00:43:15.453 --> 00:43:16.427
>> This piece

00:43:17.625 --> 00:43:18.405
>> Right, so

00:43:18.405 --> 00:43:21.865
the other point,
part that's in it is discarded.

00:43:21.865 --> 00:43:25.605
Like the compiler never even,
basically, reads those, line 15.

00:43:25.605 --> 00:43:27.595
>> Correct, you can have,
even, syntax errors here,

00:43:27.595 --> 00:43:29.082
it doesn't even matter.

00:43:29.082 --> 00:43:30.232
I actually didn't know that.

00:43:30.232 --> 00:43:32.942
>> Because it's just
text that skips, right?

00:43:32.942 --> 00:43:34.752
>> Party on, yes so

00:43:34.752 --> 00:43:36.962
the compiler literally
doesn't see those lines.

00:43:36.962 --> 00:43:39.702
>> Yes, and then the other nice
thing is because the way it's

00:43:39.702 --> 00:43:41.932
set up here,
because it's a similar project.

00:43:41.932 --> 00:43:43.772
Project reference is also
doing the right thing, so

00:43:43.772 --> 00:43:45.808
you see that all these project
references is just reference.

00:43:45.808 --> 00:43:48.891
This GPS project and
they would only get the correct

00:43:48.891 --> 00:43:51.687
implementation depending
on who they are, so

00:43:51.687 --> 00:43:54.340
this project would get
[INAUDIBLE] WP side and

00:43:54.340 --> 00:43:57.078
this project gets
the .Net framework side.

00:43:57.078 --> 00:43:59.642
So even if you don't [INAUDIBLE]
package using multi target

00:43:59.642 --> 00:44:02.259
[INAUDIBLE] solution can just
drastically reduce the number

00:44:02.259 --> 00:44:05.155
of projects you have to think
about and having to maintain.

00:44:05.155 --> 00:44:06.680
[INAUDIBLE] a really
powerful feature.

00:44:08.280 --> 00:44:09.230
>> Cool, I like it.

00:44:09.230 --> 00:44:10.118
>> Yeah, it's pretty nice.

00:44:11.516 --> 00:44:15.371
Actually a good question, one of
the things we didn't talk about

00:44:15.371 --> 00:44:18.736
is, I mean I guess it doesn't
matter now since we shipped

00:44:18.736 --> 00:44:21.350
Visual Studio 2015.3,
>> Right.

00:44:21.350 --> 00:44:22.860
>> But just to drive home
the point that if you

00:44:22.860 --> 00:44:27.270
wanna use this stuff you need
those Visual Studio 2017 15.3.

00:44:27.270 --> 00:44:28.390
>> Yes.
>> Shifted like a week ago.

00:44:28.390 --> 00:44:30.940
>> So, most of the stuff I
just showed you, like multi

00:44:30.940 --> 00:44:32.990
targeting, I think is something
that should go earlier.

00:44:32.990 --> 00:44:33.590
>> Yes.

00:44:33.590 --> 00:44:35.794
>> But as soon as you talk
about .NET Core 2.0 and

00:44:35.794 --> 00:44:38.390
.NET Standard 2.0,
you have to be in 15.3.

00:44:38.390 --> 00:44:40.500
>> Right.
>> You can't be in 15.2 or 15.1.

00:44:40.500 --> 00:44:42.270
>> It basically doesn't work.

00:44:42.270 --> 00:44:42.820
>> Yes.

00:44:42.820 --> 00:44:45.030
>> I don't even know what the
errors are you're getting, but

00:44:45.030 --> 00:44:46.699
there's probably some
unhappiness involved.

00:44:47.990 --> 00:44:48.850
>> When you go along that path.

00:44:50.540 --> 00:44:52.650
Alright, so the one URL
that you should remember is

00:44:52.650 --> 00:44:54.140
this one here.

00:44:54.140 --> 00:44:59.013
It's netstandardfaq which points
to a document I showed earlier

00:44:59.013 --> 00:45:00.882
which is illuminating.

00:45:00.882 --> 00:45:03.847
So if you have questions that
we haven't answered yet,

00:45:03.847 --> 00:45:06.700
I would only just add a new
section to this thing here.

00:45:06.700 --> 00:45:08.250
>> Right.
>> And so I have a whole bunch

00:45:08.250 --> 00:45:11.139
of questions being answered
here, for example,

00:45:11.139 --> 00:45:13.220
Why is James for example?

00:45:13.220 --> 00:45:16.362
And how does version work?

00:45:16.362 --> 00:45:19.401
Almost everything we just
talked about is listed here and

00:45:19.401 --> 00:45:22.900
from here, the very top, we also
have links to other resources.

00:45:22.900 --> 00:45:27.058
So that's why it's basically
your one stop shop, I guess, for

00:45:27.058 --> 00:45:28.540
everything.

00:45:28.540 --> 00:45:29.610
We link to our docs,

00:45:29.610 --> 00:45:32.049
we have a video series that
we created on YouTube.

00:45:33.050 --> 00:45:36.430
Our conceptual docs, our API
docs are being linked here.

00:45:36.430 --> 00:45:39.293
So, for example, we want to find
out what's actually in doc and

00:45:39.293 --> 00:45:41.319
send it 2.0,
you can actually browse it.

00:45:41.319 --> 00:45:43.936
You don't have to just use
intelligence in Studio.

00:45:43.936 --> 00:45:46.702
>> I know, that's that
experience is really nice.

00:45:46.702 --> 00:45:49.703
>> It's super nice, especially
when you search for types,

00:45:49.703 --> 00:45:52.300
it's super responsive, right?

00:45:52.300 --> 00:45:54.238
Something we never
had before in MSDN.

00:45:54.238 --> 00:45:55.542
>> No, definitely not.

00:45:55.542 --> 00:45:58.660
>> We actually have to use
the whole screen, it's amazing.

00:45:58.660 --> 00:46:00.190
>> Turns out you can.

00:46:00.190 --> 00:46:02.104
>> It's almost
better than GitHub,

00:46:02.104 --> 00:46:04.152
because GitHub only
uses that part.

00:46:04.152 --> 00:46:07.080
Anyway, so, that's the URL
you wanna remember.

00:46:07.080 --> 00:46:10.105
And then of course if you have
questions you can reach me on

00:46:10.105 --> 00:46:12.069
Twitter, you can
shoot me an email.

00:46:12.069 --> 00:46:13.001
I get a ton of emails, so

00:46:13.001 --> 00:46:15.480
I'm gonna be super responsive
on emails, I have hired

00:46:15.480 --> 00:46:18.370
an extra hand you can hit me
on Twitter than on email.

00:46:18.370 --> 00:46:19.450
>> Yeah, cuz that's what you do.

00:46:19.450 --> 00:46:21.026
Get home, and
then it's just Twitter for

00:46:21.026 --> 00:46:21.980
the rest of the evening.

00:46:21.980 --> 00:46:26.768
>> That's totally true and then
my wife gets 5% of the time.

00:46:26.768 --> 00:46:30.459
>> Okay, I think we're kinda
coming to a close here.

00:46:30.459 --> 00:46:32.760
I think I've basically
asked all my questions.

00:46:32.760 --> 00:46:33.966
>> Sweet.
>> Actually no,

00:46:33.966 --> 00:46:36.168
I have a good one that
a lot of people ask.

00:46:36.168 --> 00:46:40.930
So the .NET Core team is

00:46:40.930 --> 00:46:44.530
starting to think about .NET
Core 2.1, big surprise.

00:46:44.530 --> 00:46:45.103
>> Yes.

00:46:45.103 --> 00:46:48.020
>> Haven't really done finished
the planning there yet, but

00:46:48.020 --> 00:46:50.933
there will be such a release,
so does that mean there will be

00:46:50.933 --> 00:46:52.980
a dot net standard 2.1
>> Yes

00:46:52.980 --> 00:46:54.640
>> At the same time.

00:46:54.640 --> 00:46:55.810
>> So not at the same time, so

00:46:55.810 --> 00:46:58.750
I mean today it's somewhat
coincidental that dot net

00:46:58.750 --> 00:47:01.220
standard 2.1 dot net core 2.1
have the same version number.

00:47:01.220 --> 00:47:02.498
>> Okay.
>> It could have been done

00:47:02.498 --> 00:47:05.087
instead .NET 3.0,
doing it in .NET Core 2.0,

00:47:05.087 --> 00:47:07.070
they're not meant
to be in lockstep.

00:47:07.070 --> 00:47:07.570
>> Okay.

00:47:09.480 --> 00:47:12.710
>> So we will ref the standard
over time as well.

00:47:12.710 --> 00:47:14.278
>> Right, so
2.0 isn't the last version.

00:47:14.278 --> 00:47:15.454
>> It's not the last one and

00:47:15.454 --> 00:47:18.760
the next one is probably going
to be called 2.1, 2.2, 2.3.

00:47:18.760 --> 00:47:22.066
But you could imagine a world,
for example, were we, let's say,

00:47:22.066 --> 00:47:23.284
we add 2.1 but

00:47:23.284 --> 00:47:26.740
then the corresponding
implements happens to be 2.2.

00:47:26.740 --> 00:47:29.180
That's entirely possible
depending on how fast we ref

00:47:29.180 --> 00:47:31.810
core with respect to
the standard, right?

00:47:31.810 --> 00:47:34.258
So, Core may ref faster than
the Standard does, because

00:47:34.258 --> 00:47:36.808
the Standard would generally
ref at the cadence where we can

00:47:36.808 --> 00:47:39.723
agree on, here's a new set of
APIs you wanna have everywhere.

00:47:39.723 --> 00:47:41.410
Let's add them to the Standard.

00:47:41.410 --> 00:47:42.510
They form a nice set.

00:47:42.510 --> 00:47:44.230
Okay, let's call the 2.1 and

00:47:44.230 --> 00:47:47.020
then we work with all the
implementers of the Standard to

00:47:47.020 --> 00:47:49.200
bump their implementation
to implement 2.1.

00:47:49.200 --> 00:47:50.770
>> Right, so
is that basically the plan,

00:47:50.770 --> 00:47:54.020
which is, new concepts,
they show up in .NET Core first?

00:47:55.490 --> 00:48:00.340
They get proven and then some
combination of being added to

00:48:00.340 --> 00:48:04.750
other implementations like
Xamarin and .NET Framework, and

00:48:04.750 --> 00:48:07.330
added to .NET Standard
happened next, is that?

00:48:07.330 --> 00:48:09.323
>> That's right, and
some of the APIs,

00:48:09.323 --> 00:48:12.314
may be existing APIs that we
haven't standardized yet,

00:48:12.314 --> 00:48:14.011
some of the APIs
may be new APIs.

00:48:14.011 --> 00:48:16.746
And so, that new API is only
going core first, I guess,

00:48:16.746 --> 00:48:19.250
when you're at least being
from a PCL standpoint,

00:48:19.250 --> 00:48:21.820
because that's the part
that's open-sourced.

00:48:21.820 --> 00:48:24.525
That's the part that we can
make changes relatively fast.

00:48:24.525 --> 00:48:27.809
And yet the general view is if
you bet APIs first in a concrete

00:48:27.809 --> 00:48:30.044
implementation, and
then from there,

00:48:30.044 --> 00:48:31.730
we put it everywhere else.

00:48:31.730 --> 00:48:34.877
>> Yeah, I guess we never
actually talked about this, even

00:48:34.877 --> 00:48:38.431
in our planning, but we ended
up here, because it's obvious.

00:48:38.431 --> 00:48:39.139
>> Yes.
>> But

00:48:39.139 --> 00:48:43.373
I guess we actually do have this
rule that we only put things in

00:48:43.373 --> 00:48:46.039
.NET standard to
can be open source.

00:48:46.039 --> 00:48:48.210
>> Yes, I mean that's
the logical side effect of

00:48:48.210 --> 00:48:49.920
using stack being open source.

00:48:49.920 --> 00:48:52.351
>> Yeah, okay, all right.

00:48:52.351 --> 00:48:53.850
>> Then that's pretty much it.

00:48:53.850 --> 00:48:57.209
>> Yeah, okay, well, people
have places to contact you.

00:48:57.209 --> 00:48:58.360
>> That's fine.

00:48:58.360 --> 00:49:00.540
>> Read our blog and
this was awesome.

00:49:00.540 --> 00:49:01.510
I learned a lot.

00:49:01.510 --> 00:49:03.150
>> Yeah,
I enjoyed it pretty much.

00:49:03.150 --> 00:49:04.170
>> Okay, thanks everyone for

00:49:04.170 --> 00:49:06.966
watching another
episode of On .NET.

00:49:06.966 --> 00:49:08.796
Appreciate it.

00:49:08.796 --> 00:49:09.296
>> Bye.

