Scott Hanselman

Referencing .NET Standard Assemblies from both .NET Core and .NET Framework

August 21, '17 Comments [39] Posted in DotNetCore | NuGet | Open Source
Sponsored By

Lots of .NET Projects sharing a .NET Standard LibraryI like getting great questions in email but I LOVE getting great questions in email with a complete and clear code repro (reproduction) that's in a git somewhere. Then I can just clone, build (many many bonus points for a clean build) and check out the bug.

I got a great .NET Core question and repro here https://github.com/ScarlettCode/Example. I forked it, fixed it, and submitted a PR. Here's the question and issue and today's fix.

The project has a C# library project (an assembly) that is written to the .NET Standard 2.0. You'll recall that the .NET Standard isn't a runtime or a library in itself, but rather an interface. They are saying that this library will work anywhere that the .NET Standard is supported, like Linux, Mac, and Windows.

Here's that main .NET Standard Library called "Example.Data" written in C#.

Then he had:

  • Windows Forms (WinForms) application in VB.NET using .NET "full" Framework 4.6
  • Console Application also using .NET Framework 4.6
  • Console Application using .NET Core 2.0

Each of these apps is referring to the Example.Data library. The Example.Data library then pulls in a database access library in the form of Microsoft.EntityFrameworkCore.InMemory via NuGet.

WinForms app -> Data Access library -> Some other library. A->B->C where B and C are packages from NuGet.

The .NET Core console builds and runs great. However, when the other projects are run you get this error:

Can't load
Could not load file or assembly
'Microsoft.EntityFrameworkCore, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=adb9793829ddae60'
or one of its dependencies. The system cannot find
the file specified.

Pretty low level error, right? First thing is to check the bin folder (the results of the compile) for a project that doesn't run. Looks like there's no Microsoft.EntityFrameworkCore there. Why not? It's assembly "C" downstream of "A" and "B". EntityFramework's assembly is referred to by the Example.Data assembly...but why didn't it get copied in?

The "full" Framework projects are using the older .csproj format and by default, they use package.config to manage dependencies. The newer projects can reference Packages as first-class references. So we need to tell ALL projects in this solution to manage and restore their packages as "PackageReferences."

I can open up the .csproj file for the Framework projects and add this line within the first <PropertyGroup> like this to change the restore style:

 <RestoreProjectStyle>PackageReference</RestoreProjectStyle>

As Oren wisely says:

"Using .NET Standard requires you to use PackageReference to eliminate the pain of “lots of packages” as well as properly handle transitive dependencies. While you may be able to use .NET Standard without PackageReference, I wouldn’t recommend it."

I can also change the default within VS's Package Management options here in this dialog.

 <RestoreProjectStyle>PackageReference</RestoreProjectStyle> Default Package management format

Hope this helps.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

How to host your own NuGet Server and Package Feed

April 13, '16 Comments [43] Posted in NuGet | NUnit
Sponsored By

Local NuGet FeedHosting your own NuGet Server, particularly when you're a company or even a small workgroup is a super useful thing. It's a great way to ensure that the build artifacts of each team are NuGet Packages and that other teams are consuming those packages, rather than loose DLLs.

A lot of folks (myself included a minute ago) don't realize that Visual Studio Team Services also offers private NuGet Feeds for your team so that's pretty sweet. But I wanted to try out was setting up my own quick NuGet Server. I could put it on a web server in my closet or up in Azure.

From the NuGet site:

There are several third-party NuGet Servers available that make remote private feeds easy to configure and set-up, including Visual Studio Team Services, MyGet, Inedo's ProGet, JFrog's Artifactory, NuGet Server, and Sonatype's Nexus. See An Overview of the NuGet Ecosystem to learn more about these options.

File Shares or Directories as NuGet Server

Starting with NuGet 3.3 you can just use a local folder and it can host a hierarchical NuGet feed. So I head out to the command line, and first make sure NuGet is up to date.

C:\Users\scott\Desktop>nuget update -self
Checking for updates from https://www.nuget.org/api/v2/.
Currently running NuGet.exe 3.3.0.
NuGet.exe is up to date.

Then I'll make a folder for my "local server" and then go there and run "nuget init source dest" where "source" is a folder I have full of *.nupkg" files.

This command adds all the packages from a flat folder of nupkgs to the destination package source in a hierarchical layout as described below. The following layout has significant performance benefits, when performing a restore or an update against your package source, compared to a folder of nupkg files.

There's two ways to run a "remote feed" handled by a Web Server, rather than a "local feed" that's just a file folder or file share. You can use NuGet.Server *or* run your own internal copy of the NuGet Gallery. The gallery is nice for large multi-user setups or enterprises. For small teams or just yourself and your CI (continuous integration) systems, use NuGet.Server.

Making a simple Web-based NuGet.Server

From Visual Studio, make an empty ASP.NET Web Application using the ASP.NET 4.x Empty template.

New Empty ASP.NET Project

Then, go to References | Manage NuGet Packages and find NuGet.Server and install it. You'll get all the the dependencies you need and your Empty Project will fill up! If you see a warning about overwriting web.config, you DO want the remote web.config so overwrite your local one.

Nuget install NuGet.Server

Next, go into your Web.config and note the packagesPath that you can set. I used C:\LocalNuGet. Run the app and you'll have a NuGet Server!

You are running NuGet.Server v2.10.0

Since my NuGet.Server is pulling from C:\LocalNuGet, as mentioned before I can take a folder filled with NuPkg files (flat) and import them with:

nuget init c:\source c:\localnuget

I can also set an API key in the web.config (or have none if I want to live dangerously) and then have my automated build push NuGet packages into my server like this:

nuget push {package file} -s http://localhost:51217/nuget {apikey}

Again, as a reminder, while you can totally do this and it's great for some enterprises, there are lots of hosted NuGet servers out there. MyGet runs on Azure, for example, and VSO/TFS also supports creating and hosting NuGet feeds.

Aside: Some folks have said that they tried NuGet.Server (again, that's the small server, not the full gallery) a few years ago and found it didn't scale or it was slow. This new version uses the Expanded Folder Format and adds significant caching, so if you've only see the "folder full of flat nupkg files" version, then you should try out this new one! It's version 2.10+. How much faster is it? First request to /nuget (cold start, no metadata cache) before was 75.266 sec and after is 8.482 sec!

The main point is that if you've got an automated build system then you really should be creating NuGet packages and publishing them to a feed. If you're consuming another group's assemblies, you should be consuming versioned packages from their feeds. Each org makes packages and they flow through the org via a NuGet server.

Important! If you are using a Network Share with NuGet.Server, make sure you have the newest version because this file folder structure can give you MAJOR performance improvements!

How do YOU handle NuGet in YOUR organization? Do you have a NuGet server, and if so, which one?


Sponsor: Big thanks to RedGate and my friends on ANTS for sponsoring the feed this week!

How can you find & fix your slowest .NET code? Boost the performance of your .NET application with the ANTS Performance Profiler. Find your bottleneck fast with performance data for code & queries. Try it free

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

NuGet Package of the Week: A different take on ASP.NET MVC Forms with ChameleonForms

February 17, '15 Comments [32] Posted in ASP.NET MVC | NuGet | NuGetPOW | Open Source
Sponsored By

One of the nice things about any modular system (like ASP.NET) is the ability to swap out the parts you don't like. As the authors of ChameleonForms state, HTML forms is a pain. It's repetitive, it's repetitive, and it's boring. While ASP.NET MVC's Form Helpers help a lot, they felt that helper methods like Html.EditorForModel didn't go far enough or give you enough flexibility. ChameleonForms adds its own templating model and attempts to be as DRY as possible. It also takes a number of issues head on like better handling for drop-down lists and lists of radio buttons, and it even supports Twitter Bootstrap 3 to you can bang out HTML forms ASAP.

ChameleonForms also is a nice example of a tidy and well-run small open source project. They've got a public Trello backlog board, excellent documentation, a continuous integration build, a good example project, and of course, they're on NuGet. Check out the other projects that the folks in the "MRCollective" work on as well, as they've got their own GitHub organization.

NuGet Install ChameleonForms

Often ChameleonForms tries to use C# for the whole form, rather than switching back and forth from Div to Html Helper. For example:

@using (var f = Html.BeginChameleonForm()) {
using (var s = f.BeginSection("Signup for an account")) {
@s.FieldFor(m => m.FirstName)
@s.FieldFor(m => m.LastName)
@s.FieldFor(m => m.Mobile).Placeholder("04XX XXX XXX")
@s.FieldFor(m => m.LicenseAgreement).InlineLabel("I agree to the terms and conditions")
}
using (var n = f.BeginNavigation()) {
@n.Submit("Create")
}
}

This is the whole form using usings for scoping, and it's nice and clean.  How about a comparison example? Here's standard ASP.NET MVC:

@using (Html.BeginForm())
{
<fieldset>
<legend>A form</legend>
<dl>
<dt>@Html.LabelFor(m => m.RequiredString, "Some string")</dt>
<dd>@Html.TextBoxFor(m => m.RequiredString) @Html.ValidationMessageFor(m => m.RequiredString)</dd>
<dt>@Html.LabelFor(m => m.SomeEnum)</dt>
<dd>@Html.DropDownListFor(m => m.SomeEnum, Enum.GetNames(typeof(SomeEnum)).Select(x => new SelectListItem {Text = ((SomeEnum)Enum.Parse(typeof(SomeEnum), x)).Humanize(), Value = x})) @Html.ValidationMessageFor(m => m.SomeEnum)</dd>
<dt>@Html.LabelFor(m => m.SomeCheckbox)</dt>
<dd>@Html.CheckBoxFor(m => m.SomeCheckbox) @Html.LabelFor(m => m.SomeCheckbox, "Are you sure?") @Html.ValidationMessageFor(m => m.SomeCheckbox)</dd>
</dl>
</fieldset>
<div class="form_navigation">
<input type="submit" value="Submit" />
</div>
}

And here is the same form with ChameleonForms.

@using (var f = Html.BeginChameleonForm()) {
using (var s = f.BeginSection("A form")) {
@s.FieldFor(m => m.RequiredString).Label("Some string")
@s.FieldFor(m => m.SomeEnum)
@s.FieldFor(m => m.SomeCheckbox).InlineLabel("Are you sure?")
}
using (var n = f.BeginNavigation()) {
@n.Submit("Submit")
}
}

But these are basic. How about something more complex? This one has a bunch of variety, a number overloads and customizations, as well as a FileUpload (note that the form is a Multipart form):

@using (var f = Html.BeginChameleonForm(method: FormMethod.Post, enctype: EncType.Multipart))
{
<p>@f.LabelFor(m => m.SomeCheckbox).Label("Are you ready for: ") @f.FieldElementFor(m => m.SomeCheckbox) @f.ValidationMessageFor(m => m.SomeCheckbox)</p>
<p>@f.FieldElementFor(m => m.RequiredStringField).TabIndex(4)</p>
using (var s = f.BeginSection("My Section!", InstructionalText(), new{@class = "aClass"}.ToHtmlAttributes()))
{
using (var ff = s.BeginFieldFor(m => m.RequiredStringField, Field.Configure().Attr("data-some-attr", "value").TabIndex(3)))
{
@ff.FieldFor(m => m.NestedField).Attr("data-attr1", "value").TabIndex(2)
@ff.FieldFor(m => m.SomeEnum).Attr("data-attr1", "value")
@ff.FieldFor(m => m.SomeEnum).Exclude(SomeEnum.SomeOtherValue)
}
@s.FieldFor(m => m.SomeCheckbox).AsDropDown()
using (var ss = s.BeginSection("Nested section"))
{
@ss.FieldFor(m => m.FileUpload).Attr("data-attr1", "value")
}
@s.FieldFor(m => m.RequiredStringField).OverrideFieldHtml(new MvcHtmlString("Custom html <b>she-yeah</b>!"))
@s.FieldFor(m => m.TextAreaField).Cols(60).Rows(5).Label("Some Label").AutoFocus().TabIndex(1)
@s.FieldFor(m => m.SomeCheckbox).InlineLabel("Some label").WithHint("Format: XXX")
@s.FieldFor(m => m.SomeCheckbox).AsRadioList().WithTrueAs("True").WithFalseAs("False")
@s.FieldFor(m => m.ListId)
@s.FieldFor(m => m.ListId).AsRadioList()
@s.FieldFor(m => m.SomeEnums)
@s.FieldFor(m => m.SomeEnumsList).AsRadioList()
@s.FieldFor(m => m.Decimal)
@s.FieldFor(m => m.Int).AsInputGroup().Append(".00").Prepend("$")
@s.FieldFor(m => m.DecimalWithFormatStringAttribute)
@s.FieldFor(m => m.NullableInt)
@s.FieldFor(m => m.Child.ChildField)
@s.FieldFor(m => m.Child.SomeEnum).AsRadioList()
@s.FieldFor(m => m.RequiredStringField).Disabled()
@s.FieldFor(m => m.RequiredStringField).Readonly()
}
using (var n = f.BeginNavigation())
{
@n.Submit("Submit")
@n.Reset("Reset")
}
}

ChameleonForms also has a special NuGet package if you're using TwitterBootstrap that changes how forms with the BeginChameleonForm method render.

ChameleonForms also has some convenient extra abilities, like being able to automatically infer/create a [DisplayName] so you don't have to. If you're doing Forms in English and your preferred Display Name will end up just being your variable name this can be a useful time saver (although you may have opinions about its purity.)

So instead of the tedium of:

[DisplayName("Email address")]
public string EmailAddress { get; set; }

[DisplayName("First name")]
public string FirstName { get; set; }

You can just say this once, picking just one...this is an example where they use HumanizedLabels.

HumanizedLabels.Register(LetterCasing.AllCaps) => "EMAIL ADDRESS"
HumanizedLabels.Register(LetterCasing.LowerCase) => "email address"
HumanizedLabels.Register(LetterCasing.Sentence) => "Email address"
HumanizedLabels.Register(LetterCasing.Title) => "Email Address"

If you've got a lot of Forms to create and they're just no fun anymore, you should definitely give ChameleonForms a try. If you're a Twitter Bootstrap shop, doubly so, as that's where ChameleonForms really shines.

I'll do a few other posts exploring different ways to for Forms in ASP.NET MVC in the coming weeks. Be sure to explore the NuGet Package of the Week Archives as well!


PLUG: Did you know I have a YouTube channel? Subscribe over here. I've got tutorials on how to effectively use Windows 8 and 8.1, Build to Build walkthroughs of the latest versions of Windows 10, and I just started a new series I'm sure you'll want to share with your family called "How to REALLY use Microsoft Office." Help me out and spread the word!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

NuGet Package of the Week: Polly wanna fluently express transient exception handling policies in .NET?

January 13, '15 Comments [13] Posted in NuGet | NuGetPOW
Sponsored By

LOL at my own post title. Pardon me.

Install-Package Polly

Michael Wolfenden has a very clever open source library called Polly. Polly is a .NET 3.5 / 4.0 / 4.5 / PCL library that allows developers to express transient exception handling policies such as Retry, Retry Forever, Wait and Retry or Circuit Breaker in a fluent manner.

Handling exceptions can be a hassle sometimes. Not just setting the try/catches up, but deciding on the policy for the catch can make the exception management code more complex than the method itself!

Polly has a fluent interface to make expressing rules like that much easier. For example:

// Single exception type
Policy
.Handle<DivideByZeroException>()

// Single exception type with condition
Policy
.Handle<SqlException>(ex => ex.Number == 1205)

// Multiple exception types
Policy
.Handle<DivideByZeroException>()
.Or<ArgumentException>()

// Multiple exception types with condition
Policy
.Handle<SqlException>(ex => ex.Number == 1205)
.Or<ArgumentException>(ex => x.ParamName == "example")

Then you can add Retry() logic, which is fantastic.

// Retry multiple times, calling an action on each retry 
// with the current exception and retry count
Policy
.Handle<DivideByZeroException>()
.Retry(3, (exception, retryCount) =>
{
// do something
});

Even do retries with multiplicative back off!

// Retry a specified number of times, using a function to 
// calculate the duration to wait between retries based on
// the current retry attempt, calling an action on each retry
// with the current exception, duration and context provided
// to Execute()
Policy
.Handle<DivideByZeroException>()
.WaitAndRetry(
5,
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
(exception, timeSpan, context) => {
// do something
}
);

Once you have set up a policy, you execute on it.

Policy
.Handle<SqlException>(ex => ex.Number == 1205)
.Or<ArgumentException>(ex => ex.ParamName == "example")
.Retry()
.Execute(() => DoSomething());

Polly also supports the more sophisticated "Circuit Breaker" policy. For more information on the Circuit Breaker pattern see:

Circuit breaker tries and then "Trips the circuit breaker" so you'll get a BrokenCircuitException for some amount of time. This is a great way to give an external system to chill for a minute if it's down. It also externalizes the concept so that you could theoretically handle a down database the same as you handle a down external web API.

// Break the circuit after the specified number of exceptions
// and keep circuit broken for the specified duration
Policy
.Handle<DivideByZeroException>()
.CircuitBreaker(2, TimeSpan.FromMinutes(1))

You can explore the code, of course, up on Github in the Polly repository. Go give the Polly project a star. They've recently added async support for .NET 4.5 as well!


Sponsor: Welcome this week's feed sponsor, Stackify! - The only developer-friendly solution that fully integrates .NET error & log management with application monitoring. Easily isolate issues and focus your efforts – Support less, Code more. Free trial

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

NuGet Package of the Week - Courtesy Flush to flush buffers earlier and optimize time to first byte

November 6, '14 Comments [24] Posted in ASP.NET | ASP.NET MVC | NuGet | NuGetPOW
Sponsored By

Yes, really. It's got to be the best name for an open source library out there. It's a great double entendre and a great name for this useful little library. Perhaps English isn't your first language, so I'll just say that a courtesy flush gives the next person a fresh bowl. ;)

However, in the computer world "flushing a buffer" means forcing a buffer to be moved along, usually to a file or the network. Rather than holding data, you flush it, and move it along.

Nik from Glimpse has a small NuGet package called Courtesy Flush. He's got a good write-up on his blog.

image

It's a library to enable easier flushing of your buffer in ASP.NET MVC. From their site:

Why Flush Early?

Flushing early can provide performance improvements in web applications and has been a recomended best practice in the web performance community since 2007.

To find out more, check out Nik's blog where he covered the benefits of flushing early in two posts:

It builds on top of ASP.NET ActionFilters, which you can apply as attributes to your methods, or call within controllers.

Let's say that you have some server-side work that's very slow. That slow operation could hold up the rendering of your page until it completes. With a pre-flush like this you can get bytes onto the network and into the user's browser faster.

Here we render some information and get it out fast before we do something that's unavoidably slow.

public ActionResult About()
{
ViewBag.Title = DateTime.Now.Second;
this.FlushHead();

Thread.Sleep(2000);
ViewBag.Message = "Your application description page.";

return View();
}

Let's think about really specifically. It's important to know WHY you would want to do this and what exactly happens in the browser.

If you have a long running, but important process (we are pretending that Thread.Sleep(2000) is important) that takes 2 seconds, no HTML is sent to the browser. It's just waiting. The timeline looks like this:

Here we didn't flush

See that blue line? We waited almost 5 seconds for the /about page, and while we were waiting, no Javascript and no CSS were being loaded. Why not? How could the browser know if it isn't seen the <head> of your HTML?

For an optimization, we could FLUSH the buffers that we have up to this point, putting the HTML that we have so far onto the network.

The Layout.cshtml we have a call to @Html.FlushHead() to get the the _Head.cshtml out and into the hands of the browser. It might look like this:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@if (ViewBag.Description != null)
{
<meta name="description" content="@ViewBag.Description">
}
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>

Here's what the SAME page looks like with the <head> flushed out first.

Here we flushed

Look closely at the timeline. Here, I'll do it for you...below shows when we flushed early versus just waiting.

See how when we flushed the head it gave the browser enough information to stat loading some css and javascript we had in the <head?> The whole page took 5 seconds, but when we flush at least we get things going early, while when we don't flush we can't do a thing until the long running task finishes.

See the difference?

See the difference? Now, to be clear, don't blindly go and add optimizations without reading the code and understanding what's going on, but this is a nice tool for our ASP.NET toolbox.

We may see a similar but even more powerful technique in ASP.NET vNext that includes async flushes at multiple points, while updating the model as data is available.


Sponsor: Big thanks to Aspose for sponsoring the feed this week! Working with Files? Aspose.Total for .NET has all the APIs you need to create, manipulate and convert Microsoft Office documents and many other formats in your applications. Start a free trial today.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb
Page 1 of 8 in the NuGet category Next Page

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.