.Net Core Best Practices - Every .Net Developer Must Know
.Net Core Best Practices - Every .Net Developer Must Know
.Net Core Best Practices - Every .Net Developer Must Know
Net
Developer Must Know
(ht t ps://aglowidit solut ions.com/blog/aut hor/saurabh/) By Saurabh Barot
Quick Summary:
.NET Core best practices are discussed in this article. When creating a web
application, the most crucial factor to consider is performance. With each
new.NET core release, Microsoft has demonstrated that.NET core is the most
powerful, versatile, and complete framework for developing powerful Web,
desktop, mobile, and cloud-based applications.
(ht t ps://wa.me/17707960077)
.NET core is one of the most popular and powerful frameworks among
developers. It’s built from the ground up to be modular, lightweight, fast, and
cross-platform. It contains the essential functionality needed to run basic.NET
core programs. Other features are available as a NuGet package that can be
added to the app as needed. As a result, the.NET core program performs better,
has a smaller memory footprint, and is easier to maintain.
The following statistics can see the popularity of the .NET core.
(ht t ps://wa.me/17707960077)
In other frameworks and libraries section
(https://insights.stackoverflow.com/survey/2021#most-loved-dreaded-
and-wanted-misc-tech-love-dread), the .NET core has scored the first spot
with 72.67%
(ht t ps://wa.me/17707960077)
Now that we know the popularity of the .NET core let’s look at some of the best
ways to help you have faster and smoother applications. However, DOTNET Core
best practices here are divided into categories. But keep in mind that various
other categories are not included here:
The .NET core best practices in this article are divided into seven categories.
They are as follows:
Logging
Dependency injection
Security
Web API
Performance
Caching (ht t ps://wa.me/17707960077)
Exception Handling
Let’s take a look at each one of them respectively:
The logging dotnet core best practice will be discussed in this section. Logging
generally takes a back place to unit testing and documentation in the software
development environment. However, logging is a useful tool for debugging in
production and gives valuable information about how your program is used in
the real world. When things go wrong, the data in logs aid both the development
and operations teams in troubleshooting and promptly resolving the issue.
Although blogs are important, not all of them are created equal. When building
them, you must follow best practices to ensure that they contain the correct
information when you need it.
(ht t ps://wa.me/17707960077)
Use Native libraries
<configuration>
<system.diagnostics>
<sources>
<source name="TraceTest"
switchName="sourceSwitch"
switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add name="console"
type="System.Diagnostics.ConsoleTraceListener">
<filter type="System.Diagnostics.EventTypeFilter"
initializeData="Error"/>
</add>
<add name="myListener"/>
<remove name="Default"/>
</listeners>
</source>
</sources>
<switches>
<add name="sourceSwitch" value="Error"/>
</switches>
</system.diagnostics>
</configuration>
Logging to the console is useful, but only for a short time. What if you need to
compare the outcomes of a series of debug tests or keep track of an event log?
You can route log messages to the most relevant (ht t ps://wa.me/17707960077)
places by writing them in
separate locations.
These requirements are easily met with TraceSource. This logging library delivers
its messages to a listner object, which then sends them to a chosen place like the
console, the Windows Event Log, or a file. Add the following code to your
configuration file to add a listener that writes to a file:
<configuration>
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="myListener" type="System.Diagnostics.TextWriterTrac
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
This snippet adds the listener object called myListener and writes your message
to a log file titled TextWriterOutput.log. Then you can use the trace class to write
text to the file:
Trace.TraceInformation("Test message.");
// You must close or flush the trace to empty the output buffer.
Trace.Flush();
You can also add a dynamic listener at runtime. The following code example
shows how to dynamically add a new listener to the Trace. Listeners collection
instead of using the static configuration file:
Trace.Listeners.Add(new TextWriterTraceListener("TextWriterOutput.log",
"myListener"));
Trace.TraceInformation("Test message.");
// You must close or flush the trace to empty the output buffer.
Trace.Flush();
The.NET SDK’s TraceSource library is useful in various contexts, but it lacks the kind
of Highlevel APIs you’d expect in a conventional logging system. Libraries like
Log4Net, Nlog, and serilog can handle the heavy work that comes with System.
Diagnostic features.
So you don’t have to, trace the source. Which library you chose will be
determined by your specific requirements, albeit they are all functionally
comparable.ConfigureLog4Net must be configured in the same way as the trace
source in your app’s configuration file.
(ht t ps://wa.me/17707960077)
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationS
</configSections>
<log4net>
<!-- In log4net, output destinations are known as appenders —>
<!-- Roll the file when it reaches 1MB -->
<appender name="LogFileAppender" type="log4net.Appender.RollingFil
<!-- Specify which file to write to -->
<param name="File" value="myLoggerFile.log"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" /
<appendToFile value="true" />
<rollingStyle value="Size" />
<!-- How many log files should we keep? -->
<maxSizeRollBackups value="2" />
<!-- Roll to a new file when current one hits 1MB -->
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<!-- The format of each line in the log -->
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %
</layout>
</appender>
<!-- Set root logger level to INFO and appender to LogFileAppende
<root>
<level value="INFO" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
(ht t ps://wa.me/17707960077)
The ALL setting logs everything, whereas the OFF setting logs nothing. These log
levels can be assigned to each logger in the configuration file. Any
communication with a priority lower than the configured level will be disregarded.
The benefit is that you can set the logging level directly in your configuration file.
You don’t have to edit the code to change the types of log messages you care
about; customized logs only require a separate config file.
Create various appenders in your config file to specify an output location for
your messages based on the logging level. This configuration, for example,
establishes two loggers: one that sends all messages at or above INFO to info.log,
and another that sends all messages at or above ERROR to error.log.
(ht t ps://wa.me/17707960077)
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationS
</configSections>
<log4net>
<!-- In log4net, output destinations are known as appenders —>
<!-- Roll the file when it reaches 1MB -->
<appender name="LogFileAppender" type="log4net.Appender.RollingFil
<!-- Specify which file to write to -->
<param name="File" value="myLoggerFile.log"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" /
<appendToFile value="true" />
<rollingStyle value="Size" />
<!-- How many log files should we keep? -->
<maxSizeRollBackups value="2" />
<!-- Roll to a new file when current one hits 1MB -->
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<!-- The format of each line in the log -->
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %
</layout>
</appender>
<!-- Set root logger level to INFO and appender to LogFileAppende
<root>
<level value="INFO" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
Each file is written by a separate logger, so you need to use both inside of your
code:
Let’s take a look at the dependency injection .net core best practices. The
following are some of the basics that you need to keep in mind.
Constructor Injection
(ht t ps://wa.me/17707960077)
Best practice for Constructor Injection
Explicitly define required dependencies in the service function Object() {
[native code] } . As a result, the service cannot be built without its
dependencies.
Assign Injected dependency to a field/property that is read-only.
Property Injection
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; namespace MyApp
{
public class ProductService
{
public ILogger<ProductService> Logger { get; set; } private re
{
_productRepository = productRepository; Logger
} public void Delete(int id)
{
_productRepository.Delete(id); Logger.LogInform
$"Deleted a product with id = {id}");
}
}
}
Only use property injection for dependencies that aren’t required. That
means your service will function properly even if these requirements aren’t
given.
If feasible, use the null object pattern and always (ht
check for null when utilizing
t ps://wa.me/17707960077)
dependencies.
Service Locator
When you resolve services within the function Object() { [native code] } , they
are released.
If feasible, avoid using the service locator pattern (if the service type is
known in the development time) because it obfuscates the
interdependencies. This means that it’s difficult to notice the dependencies
while building a service instance. This is particularly helpful for unit testing,
where you might want to simulate some service dependencies.
Singleton Services
Next on the list is singleton services. Singleton services are generally designed to
keep an application state. A cache is a good example:
File service simply caches file contents to reduce disk reads. This service should
be registered as a singleton, and otherwise, caching will not work as expected.
This section will cover some of the security holes in a .NET core application. Let’s
start by listing down some of the DOTNET core best practices for security:
Never send sensitive information to the server in the form itself, such as
passwords or credit card numbers. Before transferring data to the server,
attackers can smell your data. When it comes to encryption algorithms, always
use hashing algorithms like md5 or SHA256. On the client-side, make sure to utilize
AES or DES, and on the server, make sure to use jQuery.
(ht t ps://wa.me/17707960077)
Always use SSL
Secure Socket Layer (SSL) is an acronym for Secure Socket Layer. It encrypts
communication between the client and the server using a very strong key. So, in
your Asp.Net Core Application’s Startup. cs, you can choose to always use Secure
Policy for Cookies.
Cross-Site Scripting
Hackers exploit Input Fields to send malicious scripts to steal user credentials and
other important data in XSS Attacks. Let’s imagine our application includes an
Add Product Form. The attacker creates a new product and adds a JavaScript
(ht t ps://wa.me/17707960077)
snippet to the product description field. Hackers nasty script will run when our
application displays that product on the product page with a description and will
collect data for what he planned.
So, how can you protect your app from cross-site scripting attacks? The best
practices listed below can help you secure your online application.
Only keep validated data in your database and use Regular Expressions on
both the client and server sides.
HTML Encoding with Razor aids the execution of such scripts.
URL Encoding can also perform XSS, so use UrlEncoder to check and encode
URL parameters.
SQL Injection attacks are one of the most methods of attack used to penetrate
users’ data for years. In this method, the attacker will put some condition or
specific special characters in the field, which causes the execution query to
change. For better understanding, let’s take a look at the example.
The following are some points to keep in mind for best practices for dotnet core
web API. (ht t ps://wa.me/17707960077)
Startup Class and the Server Configuration
The configuration services method for registering services and the configuration
method for adding middleware components to the application’s pipeline are
found in the starting class. As a result, it’s best to maintain the configuration
service mechanism as clean and dependable as feasible. Of course, we must
write the code to register the services within that method, but we may do so in a
maintainable and reusable manner by utilizing the Extension method. Let’s have a
look at how to register CORS incorrectly.
Although this will work fine, imagine the size of this method after registering
dozens of services.The better way is to create the extension class with the static
method.
(ht t ps://wa.me/17707960077)
public static class ServiceExtensions
{
public static void ConfigureCors(this IServiceCollection services
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
});
}
}
And then just to call this extension method upon the IServiceCollection type:
It’s really simple to do so in.NET Core. You must navigate to the appsetting.json
file, which will be expanded to reveal the app settings. The file Development.json
contains information about the development process. All of the parameters in
this file will be used in the development environment. Another file, app settings,
should be included. To use it in a production environment, type production.json.
We can keep different app settings files in this location, and the.NET core will
provide us with the appropriate settings based on the environment our
application is in. (ht t ps://wa.me/17707960077)
Data Access Layer (DAL)
The DAL is implemented inside the main project and initiated in every controller in
many cases. This is not something we should do. We should always construct a
separate service while working with DAL. This is critical for the.NET core project
since we may register DAL as a separate service inside the IOC (Inversion of
Control) container when we have it as a separate service. The IOC is a built-in
part of the.NET core, and by registering DAL as a service inside it, we may use it in
any class via function Object() { [native code] } injection. The interface should
always be the basis for repository logic, and keeping it general will enable
reusability.
Controllers
There shouldn’t be business logic inside it. The controller should always be as
clean as possible. So, our controllers should be responsible for accepting the
service instance through the constructor injection and organizing HTTP action
methods (GET, POST, PUT, DELETE, PATCH..)
(ht t ps://wa.me/17707960077)
public class OwnerController: Controller
{
private ILoggerManager _logger;
private IRepoService _repoService;
The new feature of the C# language allows you to use keywords like async and
await to implement asynchronous programming. Asynchronous programming
allows concurrent code execution and avoids blocking the execution when
conducting intensive I/O tasks such as connecting to external sources such as
web apps.
Let’s take a look at the section explaining guidelines for .net core best practices
for caching.
In.NET core, the standard interfaces IMemoryCache and IDistributed Cache have
built-in mechanisms for caching data.
IMemoryCache
services.AddMemoryCache();
IDistributed Cache
services.AddDistributedMemoryCache();
(ht t ps://wa.me/17707960077)
services.AddDistributedRedisCache (option =>
});
The static files middleware is used to provide images and other static files. A
typical initial registration in the Configure function. This is how cs appears:
app.UseStaticFiles();
This code will allow static files to be served, but not in the most efficient manner.
Because no-cache headers are used by default, the browser will repeatedly
request these files, delaying your site and adding to the load on your server.
The good news is that enabling browser caching is as simple as changing the
static file registration code. We’ve set caching to a year here:
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = (context) =>
{
var headers = context.Context.Response.GetTypedHeaders();
A Well-designed app handles exceptions and errors to prevent app crashes. This
section describes .NET core best practices for handling and creating exceptions.
Try/catch blocks should be used around code that could potentially create an
exception to recover your code. Always order exceptions in catch blocks from
most derived to least derived. An exception is the root of all exceptions. A catch
clause preceded by a catch clause for a base exception class does not handle
more derived exceptions. If your code is unable to recover from an exception,
don’t capture it. If feasible, enable methods farther up the call stack to recover.
Using statements or, finally, blocks, clean up the resources that have been
assigned. When exceptions are thrown, it is preferable to use statements to clean
up resources automatically. To clean up resources that don’t implement
IDisposable, use finally blocks. Even when exceptions are thrown, code in a finally
clause is usually always performed.
Consider handling scenarios that are likely to occur but may cause an exception
in a way that avoids the exception. You’ll get an InvalidOperationException if you
try to close a connection that has already been closed. You can avoid this by
using an if statement to check the state of the connection before closing it.
(ht t ps://wa.me/17707960077)
if (conn.State != ConnectionState.Closed)
{
conn.Close();
}
You can catch the InvalidOperationException exception if you don’t check the
connection state before closing it.
try
{
conn.Close();
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.GetType().FullName);
Console.WriteLine(ex.Message);
}
When a preset exception class does not apply, create a new one. Consider the
following scenario:
If a property set or method call isn’t appropriate for the object’s present
state, throw an InvalidOperationException exception.
(ht t ps://wa.me/17707960077)
If improper parameters are given, throw an ArgumentException exception or
one of the preset classes derived from ArgumentException.
Conclusion
That’s all there is to it! These were some of the.NET core best practices
categories. I hope these suggestions will assist you in improving the performance
of your.NET Core application. The primary goal was to familiarise you with some
of the most effective strategies for developing.NET code projects. Try to
implement the majority of these.NET core recommended practices to assist you
in improving the performance of your next project. If you face any problems while
putting this list together or making adjustments, our professional team can assist
you with answers. .NET core is one of our strong skills after almost a decade in the
industry. Let’s talk about your requirements.
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/hire-developers/)
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/cost -t o-build-grocery-app/)
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/t axi-booking-app-development /)
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/eLearning-app-development /)
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/online-medicine-delivery-app-development /)
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/ecommerce-solut ions/)
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/on-demand-app-development /)
RECENT POST S
POPULAR POST S
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/hire-angularjs-developers/)
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/hire-ruby-on-rails-developers/)
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/hire-android-app-developers/)
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/hire-ios-developers/)
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/blog/aut hor/saurabh/)
RELAT ED POST S
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/blog/best -react -st at e-management -t ools/)
ENTERPRISE
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/blog/pyt hon-opt imizat ion/)
WEB
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/blog/pros-and-cons-of-react js/)
WEB
(ht t ps://wa.me/17707960077)
Trusted by Top Leading
Companies
in USA, Canada, Australia, UK and UAE
Very professional, Accurate and They are great at what they do.
Efficient team despite all the Very easy to communicate with
changes I had them do. I look and they came through faster
forward to working with them than i hoped. They delivered
again. everything I wanted and more! I
will certainly use them again!
(ht t ps://wa.me/17707960077)
Discussion is the key to success!!!
Talk to us in person
sales@aglowiditsolutions.com (mailto:sales@aglowiditsolutions.com)
aglowid (skype:aglowid?call)
(ht t ps://wa.me/17707960077)
(ht t p
s://w
(ht t p ww.li (ht t p
s://w nkedi s://w
ww.f n.co ww.in (ht t p
aceb m/co st agr (ht t p s://w
ook.c (ht t p mpan am.c s://dr ww.b
om/A s://t y/agl om/a ibbbl ehan
glowi wit t e owid- glowi e.co ce.ne
dIt So r.com it - dit sol m/ag t /agl
lut ion /Aglo solut i ut ion lowid owid/
s) wid) ons) s) /) )
Full Name
Email Address
Message
(ht t ps://wa.me/17707960077)
(ht t ps://aglowidit solut ions.com/blog/lat est -android-feat ures/)
Android 13 Latest Features | What’s new in Tiramisu?
(ht t ps://aglowidit solut ions.com/blog/lat est -android-feat ures/)
24 March, 2022
Useful Links
- Home (https://aglowiditsolutions.com/)
- About Us (https://aglowiditsolutions.com/about-us/)
- Services (https://aglowiditsolutions.com/our-services/)
- Work (https://aglowiditsolutions.com/portfolio/)
- Blog (https://aglowiditsolutions.com/blog/)
- Careers (https://aglowiditsolutions.com/careers/)
- Contact Us (https://aglowiditsolutions.com/contact-us/)
(ht t ps://wa.me/17707960077)
(ht t ps://www.dmca.com/Prot ect ion/St at us.aspx?ID=55a40a01-ac8a-4b4b-
acc2-43a681cc396d&refurl=ht t ps://aglowidit solut ions.com/)
Brochure (https://1qkeyv41u1op36vgbm47q0i6-wpengine.netdna-ssl.com/wp-
content/uploads/2019/07/Aglowid-IT-Solutions-Company-Profile.pdf)
(ht t ps://wa.me/17707960077)