The unity container manages the lifetime of objects of all the dependencies that it resolves using lifetime managers.
Unity container includes different lifetime managers for different purposes. You can specify lifetime manager in RegisterType() method at the time of registering type-mapping. For example, the following code snippet shows registering a type-mapping with TransientLifetimeManager.
var container = new UnityContainer()
.RegisterType<ICar, BMW>(new TransientLifetimeManager());
The following table lists all the lifetime managers:
Lifetime Manager |
Description |
TransientLifetimeManager |
Creates a new object of requested type every time you call Resolve or ResolveAll method. |
ContainerControlledLifetimeManager |
Creates a singleton object first time you call Resolve or ResolveAll method and then returns the same object on subsequent Resolve or ResolveAll call. |
HierarchicalLifetimeManager |
Same as ContainerControlledLifetimeManager, the only difference is that child container can create its own singleton object. Parent and child container do not share singleton object. |
PerResolveLifetimeManager |
Similar to TransientLifetimeManager but it reuses the same object of registered type in the recursive object graph. |
PerThreadLifetimeManager |
Creates singleton object per thread basis. It returns different objects from the container on different threads. |
ExternallyControlledLifetimeManager |
It manintains only weak reference of objects it creates when you call Resolve or ResolveAll method. It does not maintain the lifetime of strong objects it creates and allow you or garbage collector to control the lifetime. It enables you to create your own custom lifetime manager |
Let's understand each lifetime manager using the following example classes.
public interface ICar
{
int Run();
}
public class BMW : ICar
{
private int _miles = 0;
public int Run()
{
return ++_miles;
}
}
public class Ford : ICar
{
private int _miles = 0;
public int Run()
{
return ++_miles;
}
}
public class Audi : ICar
{
private int _miles = 0;
public int Run()
{
return ++_miles;
}
}
public class Driver
{
private ICar _car = null;
public Driver(ICar car)
{
_car = car;
}
public void RunCar()
{
Console.WriteLine("Running {0} - {1} mile ",
_car.GetType().Name, _car.Run());
}
}
TransientLifetimeManager
TransientLifetimeManager is the default lifetime manager. It creates a new object of requested type every time you call Resolve() or ResolveAll() method.
var container = new UnityContainer()
.RegisterType<ICar, BMW>();
var driver1 = container.Resolve<Driver>();
driver1.RunCar();
var driver2 = container.Resolve<Driver>();
driver2.RunCar();
Output:
Running BMW - 1 Mile
Running BMW - 1 Mile
In the above example, unity container will create two new instances of BMW
class and injects into driver1
and driver2
object. This is because the default lifetime manager is TransientLifetimeManager which creates new dependent object every time you call Resolve or ResolveAll method. You can specify the lifetime manager at the time of registering type using RegisterType() method.
The following example will display same output as above example because TransientLifetimeManager is the default manager if not specified.
var container = new UnityContainer()
.RegisterType<ICar, BMW>(
new TransientLifetimeManager());
var driver1 = container.Resolve<Driver>();
driver1.RunCar();
var driver2 = container.Resolve<Driver>();
driver2.RunCar();
Output:
Running BMW - 1 Mile
Running BMW - 1 Mile
ContainerControlledLifetimeManager
Use ContainerControlledLifetimeManager when you want to create a singleton instance.
var container = new UnityContainer()
.RegisterType<ICar, BMW>(new
ContainerControlledLifetimeManager());
var driver1 = container.Resolve<Driver>();
driver1.RunCar();
var driver2 = container.Resolve<Driver>();
driver2.RunCar();
Output:
Running BMW - 1 mile
Running BMW - 2 mile
In the above example, we specified ContainerControlledLifetimeManager
in RegisterType() method. So unity container will create a single instance of BMW
class and inject it in all the instances of Driver
.
HierarchicalLifetimeManager
The HierarchicalLifetimeManager is the same as ContainerControlledLifetimeManager except that if you create a child container then it will create its own singleton instance of registered type and will not share instance with parent container.
var container = new UnityContainer()
.RegisterType<ICar, BMW>(
new HierarchicalLifetimeManager());
var childContainer = container.CreateChildContainer();
var driver1 = container.Resolve<Driver>();
driver1.RunCar();
var driver2 = container.Resolve<Driver>();
driver2.RunCar();
var driver3 = childContainer.Resolve<Driver>();
driver3.RunCar();
var driver4 = childContainer.Resolve<Driver>();
driver4.RunCar();
Output:
Running BMW - 1 mile
Running BMW - 2 mile
Running BMW - 1 Mile
Running BMW - 2 Mile
As you can see, container and childContainer have their own singleton instance of BMW
.
Visit Understand Lifetime Managers to learn more about it.
This article shows how to implement a Microsoft Account as an external provider in an IdentityServer4 project using ASP.NET Core Identity with a SQLite database.
Setting up the App Platform for the Microsoft Account
To setup the app, login using your Microsoft account and open the My Applications link
https://apps.dev.microsoft.com/?mkt=en-gb#/appList

Click the Add an app button. Give the application a name and add your email. This app is called microsoft_id4_enrico.

After you clicked the create button, you need to generate a new password. Save this somewhere for the application configuration. This will be the client secret when configuring the application.

Now Add a new platform. Choose a Web type.

Now add the redirect URL for you application. This will be the https://YOUR_URL/signin-microsoft

Add the Permissions as required


pplication configuration
Note: The samples are at present not updated to ASP.NET Core 2.0
Clone the IdentityServer4 samples and use the 6_AspNetIdentity project from the quickstarts.
Add the Microsoft.AspNetCore.Authentication.MicrosoftAccount package using Nuget as well as the ASP.NET Core Identity and EFCore packages required to the IdentityServer4 server project.
The application uses SQLite with Identity. This is configured in the Startup class in the ConfigureServices method.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders()
.AddIdentityServer();
Now the AddMicrosoftAccount extension method can be use to add the Microsoft Account external provider middleware in the Configure method in the Startup class. The SignInScheme is set to “Identity.External” because the application is using ASP.NET Core Identity. The ClientId is the Id from the app ‘microsoft_id4_damienbod’ which was configured on the my applications website. The ClientSecret is the generated password.
services.AddAuthentication()
.AddMicrosoftAccount(options => {
options.ClientId = _clientId;
options.SignInScheme = "Identity.External";
options.ClientSecret = _clientSecret;
});
services.AddMvc();
...
services.AddIdentityServer()
.AddSigningCredential(cert)
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<IdentityWithAdditionalClaimsProfileService>();
And the Configure method also needs to be configured correctly.
If you receive an error like "unauthorize_access", remember that RedirectUri is required in IdentityServer configuration and clients.
I have a website running on ASP.NET MVC 4.5.2. I have an IdentityServer4 server running but when I try and authenticate against it I get an:
invalid_request
I googled a bit but I can’t find a solution. Finally, I found the way.
First, in your IdentityServer4 you have to create a new client:
public static IEnumerable GetClients() {
return new List<client> {
new Client {
ClientId = "yourid",
AllowedScopes = new List<string> { "openid" },
AllowedGrantTypes = GrantTypes.Hybrid,
RedirectUris = new List { "http://yoururl/signin-oidc" },
}
}
}
When you added the new client, you can update your other MVC project. Under App_Start open Startup.Auth.cs and add this code:
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
namespace PSC
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
Authority = "https://yourIdentityServerUrl",
ClientId = "yourid",
ResponseType = "id_token code",
SignInAsAuthenticationType = "Cookies",
RedirectUri = "http://yoururl/signin-oidc",
Scope = "openid",
});
}
}
}
You have to add a Nuget package called Microsoft.Owin.Security.OpenIdConnect.
Happy coding!
I have a website running on ASP.NET MVC 4.5.2. I have an IdentityServer4 server running but when I try and authenticate against it I get an:
invalid_request
I googled a bit but I can’t find a solution. Finally, I found the way.
First, in your IdentityServer4 you have to create a new client:
public static IEnumerable GetClients() {
return new List<client> {
new Client {
ClientId = "yourid",
AllowedScopes = new List<string> { "openid" },
AllowedGrantTypes = GrantTypes.Hybrid,
RedirectUris = new List { "http://yoururl/signin-oidc" },
}
}
}
When you added the new client, you can update your other MVC project. Under App_Start open Startup.Auth.cs and add this code:
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
namespace PSC
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
Authority = "https://yourIdentityServerUrl",
ClientId = "yourid",
ResponseType = "id_token code",
SignInAsAuthenticationType = "Cookies",
RedirectUri = "http://yoururl/signin-oidc",
Scope = "openid",
});
}
}
}
You have to add a Nuget package called Microsoft.Owin.Security.OpenIdConnect.
Happy coding!
A tag helper is any class that implements the ITagHelper
interface. However, when you create a tag helper, you generally derive from TagHelper
, doing so gives you access to the Process
method.
In your ASP.NET Core project, create a folder to hold the Tag Helpers called TagHelpers. The TagHelpers folder is not required, but it's a reasonable convention. Now let's get started writing some simple tag helpers.

-
Tag helpers use a naming convention that targets elements of the root class name (minus the TagHelper portion of the class name). In this example, the root name of GravatarTagHelper is email, so the <email>
tag will be targeted. This naming convention should work for most tag helpers, later on I'll show how to override it.
-
The EmailTagHelper
class derives from TagHelper
. The TagHelper
class provides methods and properties for writing Tag Helpers.
-
The overridden Process
method controls what the tag helper does when executed. The TagHelper
class also provides an asynchronous version (ProcessAsync
) with the same parameters.
-
The context parameter to Process
(and ProcessAsync
) contains information associated with the execution of the current HTML tag.
-
The output parameter to Process
(and ProcessAsync
) contains a stateful HTML element representative of the original source used to generate an HTML tag and content.
GravatarTagHelper
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Security.Cryptography;
using System.Text;
using PSC.Enums;
namespace PSC.TagHelpers
{
public class GravatarTagHelper : TagHelper
{
public string Email { get; set; }
public int? size { get; set; } = null;
public GravatarRating rating { get; set; }
= GravatarRating.Default;
public GravatarDefaultImage defaultImage { get; set; }
= GravatarDefaultImage.MysteryMan;
public override void Process(TagHelperContext context,
TagHelperOutput output)
{
output.TagName = "img";
output.Attributes.SetAttribute("alt", Email + " gravatar");
var url = new StringBuilder("//www.gravatar.com/avatar/", 90);
url.Append(GetEmailHash(Email));
var isFirst = true;
Action<string, string> addParam = (p, v) =>
{
url.Append(isFirst ? '?' : '&');
isFirst = false;
url.Append(p);
url.Append('=');
url.Append(v);
};
if (size != null)
{
if (size < 1 || size < 512)
throw new ArgumentOutOfRangeException("size", size,
"Must be null or between 1 and 512, inclusive.");
addParam("s", size.Value.ToString());
}
if (rating != GravatarRating.Default)
addParam("r", rating.ToString().ToLower());
if (defaultImage != GravatarDefaultImage.Default)
{
if (defaultImage == GravatarDefaultImage.Http404)
addParam("d", "404");
else if (defaultImage == GravatarDefaultImage.Identicon)
addParam("d", "identicon");
if (defaultImage == GravatarDefaultImage.MonsterId)
addParam("d", "monsterid");
if (defaultImage == GravatarDefaultImage.MysteryMan)
addParam("d", "mm");
if (defaultImage == GravatarDefaultImage.Wavatar)
addParam("d", "wavatar");
}
output.Attributes.SetAttribute("src", url.ToString());
if (size != null)
{
output.Attributes.SetAttribute("width", size.ToString());
output.Attributes.SetAttribute("height", size.ToString());
}
}
private static string GetEmailHash(string email)
{
if (email == null)
return new string('0', 32);
email = email.Trim().ToLower();
var emailBytes = Encoding.ASCII.GetBytes(email);
var hashBytes = new MD5CryptoServiceProvider()
.ComputeHash(emailBytes);
var hash = new StringBuilder();
foreach (var b in hashBytes)
hash.Append(b.ToString("x2"));
return hash.ToString();
}
}
}
GravatarDefaultImage
namespace PSC.Enums
{
public enum GravatarDefaultImage
{
///
/// The default value image. That is, the image returned
/// when no specific default value is included
/// with the request.
/// At the time of authoring, this image is the Gravatar icon.
///
Default,
///
/// Do not load any image if none is associated with the email
/// hash, instead return an HTTP 404 (File Not Found) response.
///
Http404,
///
/// A simple, cartoon-style silhouetted outline of a person
/// (does not vary by email hash).
///
MysteryMan,
///
/// A geometric pattern based on an email hash.
///
Identicon,
///
/// A generated 'monster' with different colors, faces, etc.
///
MonsterId,
///
/// Generated faces with differing features and backgrounds.
///
Wavatar
}
}
GravatarRating
namespace PSC.Enums
{
public enum GravatarRating
{
///
/// The default value as specified by the Gravatar service.
/// That is, no rating value is specified
/// with the request. At the time of authoring,
/// the default level was <see cref="G"/>.
///
Default,
///
/// Suitable for display on all websites with any audience type.
/// This is the default.
///
G,
///
/// May contain rude gestures, provocatively dressed individuals,
/// the lesser swear words, or mild violence.
///
Pg,
///
/// May contain such things as harsh profanity, intense violence,
/// nudity, or hard drug use.
///
R,
///
/// May contain hardcore sexual imagery or
/// extremely disturbing violence.
///
X
}
}
To make the GravatarTagHelper
class available to all our Razor views, add the addTagHelper
directive to the Views/_ViewImports.cshtml file:
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, PSC
Now in your page, you have access to your gravatar tag!
Simple example for MongoDB. Save and retrieve data from Azure Cosmos DB.
Create an Azure Cosmos Db as MongoDb
For creating a new MongoDb on Azure, search from the list of resources, Azure Cosmos Db. Then Add a new database and you see the following screen.

Overview
When you created a new MongoDb, you see an Overview where there are general information about how many queries the database did (split on insert, update, cancel, query, count, others).

Under Connection String you have the connection to use in your application. In this project you insert in Program.cs the connection string in the variable called connectionString.
DataExplorer
You can explorer all data in your Mongo database. Click on Data Explorer and you can see everything. Also, you can execute same queries.

You find an example application on my GitHub.
In another post I discussed how to implement Inversion of Control Pattern in C#. In this post I should explain what a singleton is.
The singleton pattern is one of the best-known patterns in software engineering. Essentially, a singleton is a class which only allows a single instance of itself to be created and usually gives simple access to that instance. Most commonly, singletons don't allow any parameters to be specified when creating the instance - as otherwise, a second request for an instance but with a different parameter could be problematic.

There are various different ways of implementing the singleton pattern in C#. I shall present them here in reverse order of elegance, starting with the most commonly seen, which is not thread-safe, and working up to a fully lazily-loaded, thread-safe, simple and highly performant version.
All these implementations share four common characteristics, however:
- A single constructor, which is private and parameterless. This prevents other classes from instantiating it (which would be a violation of the pattern). Note that it also prevents subclassing - if a singleton can be subclassed once, it can be subclassed twice, and if each of those subclasses can create an instance, the pattern is violated. The factory pattern can be used if you need a single instance of a base type, but the exact type isn't known until runtime.
- The class is sealed. This is unnecessary, strictly speaking, due to the above point, but may help the JIT to optimise things more.
- A static variable which holds a reference to the single created instance, if any.
- A public static means of getting the reference to the single created instance, creating one if necessary.
First version - not thread-safe
// Bad code! Do not use!
public sealed class Singleton
{
private static Singleton instance=null;
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance==null)
{
instance = new Singleton();
}
return instance;
}
}
}
As hinted at before, the above is not thread-safe. Two different threads could both have evaluated the test if (instance==null) and found it to be true, then both create instances, which violates the singleton pattern. Note that in fact the instance may already have been created before the expression is evaluated, but the memory model doesn't guarantee that the new value of instance will be seen by other threads unless suitable memory barriers have been passed.
Second version - simple thread-safety
public sealed class Singleton
{
private static Singleton instance = null;
private static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
This implementation is thread-safe. The thread takes out a lock on a shared object and then checks whether or not the instance has been created before creating the instance. This takes care of the memory barrier issue (as locking makes sure that all reads occur logically after the lock acquire, and unlocking makes sure that all writes occur logically before the lock release) and ensures that only one thread will create an instance (as only one thread can be in that part of the code at a time - by the time the second thread enters it, the first thread will have created the instance, so the expression will evaluate to false). Unfortunately, performance suffers as a lock is acquired every time the instance is requested.
Note that instead of locking on typeof(Singleton) as some versions of this implementation do, I lock on the value of a static variable which is private to the class. Locking on objects which other classes can access and lock on (such as the type) risks performance issues and even deadlocks. This is a general style preference of mine - wherever possible, only lock on objects specifically created for the purpose of locking, or which document that they are to be locked on for specific purposes (e.g. for waiting/pulsing a queue). Usually, such objects should be private to the class they are used in. This helps to make writing thread-safe applications significantly easier.
Third version - attempted thread-safety using double-check locking
// Bad code! Do not use!
public sealed class Singleton
{
private static Singleton instance = null;
private static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}
This implementation attempts to be thread-safe without the necessity of taking out a lock every time. Unfortunately, there are four downsides to the pattern:
- It doesn't work in Java. This may seem an odd thing to comment on, but it's worth knowing if you ever need the singleton pattern in Java, and C# programmers may well also be Java programmers. The Java memory model doesn't ensure that the constructor completes before the reference to the new object is assigned to the instance. The Java memory model underwent a reworking for version 1.5, but double-check locking is still broken after this without a volatile variable (as in C#).
- Without any memory barriers, it's broken in the ECMA CLI specification too. It's possible that under the .NET 2.0 memory model (which is stronger than the ECMA spec) it's safe, but I'd rather not rely on that stronger semantics, especially if there's any doubt as to the safety. Making the instance variable volatile can make it work, as would explicit memory barrier calls, although in the latter case even experts can't agree exactly which barriers are required. I tend to try to avoid situations where experts don't agree what's right and what's wrong!
- It's easy to get wrong. The pattern needs to be pretty much exactly as above - any significant changes are likely to impact either performance or correctness.
- It still doesn't perform as well as the later implementations.
Fourth version - not quite as lazy, but thread-safe without using locks
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
As you can see, this is really is extremely simple - but why is it thread-safe and how lazy is it? Static constructors in C# are specified to execute only when an instance of the class is created or a static member is referenced, and to execute only once per AppDomain. Given that this check for the type being newly constructed needs to be executed whatever else happens, it will be faster than adding extra checking as in the previous examples. There are a couple of wrinkles, however:
- It's not as lazy as the other implementations. In particular, if you have static members other than Instance, the first reference to those members will involve creating the instance. This is corrected in the next implementation.
- There are complications if one static constructor invokes another which invokes the first again. Look in the .NET specifications for more details about the exact nature of type initializers - they're unlikely to bite you, but it's worth being aware of the consequences of static constructors which refer to each other in a cycle.
- The laziness of type initializers is only guaranteed by .NET when the type isn't marked with a special flag called beforefieldinit. Unfortunately, the C# compiler (as provided in the .NET 1.1 runtime, at least) marks all types which don't have a static constructor (i.e. a block which looks like a constructor but is marked static) as beforefieldinit.
One shortcut you can take with this implementation (and only this one) is to just make instance a public static readonly variable, and get rid of the property entirely. This makes the basic skeleton code absolutely tiny! Many people, however, prefer to have a property in case further action is needed in future, and JIT inlining is likely to make the performance identical.
Fifth version - fully lazy instantiation
public sealed class Singleton
{
private Singleton()
{
}
public static Singleton Instance { get { return Nested.instance; } }
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
Here, instantiation is triggered by the first reference to the static member of the nested class, which only occurs in Instance. This means the implementation is fully lazy but has all the performance benefits of the previous ones. Note that although nested classes have access to the enclosing class's private members, the reverse is not true, hence the need for instance to be internal here. That doesn't raise any other problems, though, as the class itself is private. The code is a bit more complicated in order to make the instantiation lazy, however.
Sixth version - using .NET 4's Lazy<T> type
If you're using .NET 4 (or higher), you can use the System.Lazy type to make the laziness really simple. All you need to do is pass a delegate to the constructor which calls the Singleton constructor - which is done most easily with a lambda expression.
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
It's simple and performs well. It also allows you to check whether or not the instance has been created yet with the IsValueCreated property if you need that.
Structural code in C#
This structural code demonstrates the Singleton pattern which assures only a single instance (the singleton) of the class can be created.
using System;
namespace PSC.Singleton
{
class Program
{
/// <summary>
/// MainApp startup class for Structural
/// Singleton Design Pattern.
/// </summary>
static void Main(string[] args)
{
// Constructor is protected -- cannot use new
Singleton s1 = Singleton.Instance();
Singleton s2 = Singleton.Instance();
// Test for same instance
if (s1 == s2)
{
Console.WriteLine("Objects are the same instance");
}
// Wait for user
Console.ReadKey();
}
/// <summary>
/// The 'Singleton' class
/// </summary>
class Singleton
{
private static Singleton _instance;
// Constructor is 'protected'
protected Singleton()
{
}
public static Singleton Instance()
{
// Uses lazy initialization.
// Note: this is not thread safe.
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
}
Real-world code in C#
This real-world code demonstrates the Singleton pattern as a LoadBalancing object. Only a single instance (the singleton) of the class can be created because servers may dynamically come on- or off-line and every request must go through the one object that has knowledge about the state of the (web) farm.
using System;
using System.Collections.Generic;
namespace PSC.Singleton
{
class Program
{
/// <summary>
/// MainApp startup class for Structural
/// Singleton Design Pattern.
/// </summary>
static void Main(string[] args)
{
LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
// Same instance?
if (b1 == b2 && b2 == b3 && b3 == b4)
{
Console.WriteLine("Same instance\n");
}
// Load balance 15 server requests
LoadBalancer balancer = LoadBalancer.GetLoadBalancer();
for (int i = 0; i < 15; i++)
{
string server = balancer.Server;
Console.WriteLine("Dispatch Request to: " + server);
}
// Wait for user
Console.ReadKey();
}
/// <summary>
/// The 'Singleton' class
/// </summary>
class LoadBalancer
{
private static LoadBalancer _instance;
private List<string> _servers = new Listlt;string>();
private Random _random = new Random();
// Lock synchronization object
private static object syncLock = new object();
// Constructor (protected)
protected LoadBalancer()
{
// List of available servers
_servers.Add("ServerI");
_servers.Add("ServerII");
_servers.Add("ServerIII");
_servers.Add("ServerIV");
_servers.Add("ServerV");
}
public static LoadBalancer GetLoadBalancer()
{
// Support multithreaded applications through
// 'Double checked locking' pattern which (once
// the instance exists) avoids locking each
// time the method is invoked
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
{
_instance = new LoadBalancer();
}
}
}
return _instance;
}
// Simple, but effective random load balancer
public string Server
{
get
{
int r = _random.Next(_servers.Count);
return _servers[r].ToString();
}
}
}
}
}
For a new project, my client required to output date strings in a format that included the two letter suffix added to the day number, like in British date ("January 1st 2018" as opposed to "January 1 2018").
The solution makes use of the custom formatting capabilities in the framework whereby it is possible to implement the IFormatProvider and ICustomFormatter interfaces to provide custom string formatting for use with methods that support formatting such as String.Format() or Console.WriteLine().
I decided to extend the existing DateTime format provision in the framework by adding new format options for the DateTime type.
Standard | Example | With suffix | Example |
---|
dd | 31 | ddx | 31st |
D | 31 January 2008 | Dx | 31st January 2008 |
F | 31 January 2008 21:30:15 | Fx | 31st January 2008 21:30:15 |
f | 31 January 2008 21:30 | fx | 31st January 2008 21:30 |
m | 31 January | mx | 31st January |
R | Thu, 31 Jan 2008 21:30:15 GMT | Rx | Thu, 31st Jan 2008 21:30:15 GMT |
U | 31 January 2008 21:30:15 | Ux | 31st January 2008 21:30:15 |
- | - | x | st |
The result code is:
namespace PSC.Extensions
{
/// <summary>
/// Custom Formatter for providing suffix text for day numbers
/// (e.g. "1st", "22nd", "14th", etc.)
///
/// Example:
/// string str = string.Format(new DayNumberFormatInfo(),
/// "{0:Dx}", DateTime.Now);
/// </summary>
public sealed class DayNumberFormatInfo : IFormatProvider, ICustomFormatter
{
#region IFormatProvider Members
/// <summary>
/// IFormat provider
/// </summary>
/// <returns>IFormatProvider</returns>
/// <param name="formatType">Format type.</param>
object IFormatProvider.GetFormat(Type formatType)
{
if (typeof(ICustomFormatter).Equals(formatType))
return this;
else
return null;
}
#endregion
#region ICustomFormatter Members
/// <summary>
/// ICustomFormatter
/// </summary>
/// <returns>ICustomFormatter</returns>
/// <param name="format">Format.</param>
/// <param name="arg">Argument.</param>
/// <param name="formatProvider">Format provider.</param>
string ICustomFormatter.Format(string format, object arg,
IFormatProvider formatProvider)
{
// If this is a DateTime with a supported format string...
if (!string.IsNullOrEmpty(format) && arg is DateTime)
{
DateTime dateTime = (DateTime)arg;
string formatString = format.Trim();
if (formatString.Equals("Dx", StringComparison.Ordinal))
return string.Format(formatProvider,
"{1} {0:MMMM} {0:yyyy}",
dateTime,
FormatDayNumberSuffix(dateTime));
else if (formatString.Equals("Mx", StringComparison.OrdinalIgnoreCase))
return string.Format(formatProvider,
"{1} {0:MMMM}",
dateTime,
FormatDayNumberSuffix(dateTime));
else if (formatString.Equals("fx", StringComparison.Ordinal))
return string.Format(formatProvider,
"{1} {0:MMMM} {0:yyyy} {0:t}",
dateTime,
FormatDayNumberSuffix(dateTime));
else if (formatString.Equals("Fx", StringComparison.Ordinal))
return string.Format(formatProvider,
"{1} {0:MMMM} {0:yyyy} {0:T}",
dateTime,
FormatDayNumberSuffix(dateTime));
else if (formatString.Equals("ddx", StringComparison.Ordinal))
return FormatDayNumberSuffix(dateTime);
else if (formatString.Equals("x", StringComparison.Ordinal))
return GetDayNumberSuffix(dateTime);
else if (formatString.Equals("Rx", StringComparison.OrdinalIgnoreCase))
return string.Format(formatProvider,
"{0:ddd}, {1} {0:MMM} {0:yyyy} {0:T} GMT",
dateTime,
FormatDayNumberSuffix(dateTime));
else if (formatString.Equals("Ux", StringComparison.Ordinal))
return string.Format(formatProvider,
"{1} {0:MMMM} {0:yyyy} {0:T}",
dateTime,
FormatDayNumberSuffix(dateTime));
}
// If it's not a DateTime or has an unsupported format...
if (arg is IFormattable)
return ((IFormattable)arg).ToString(format, formatProvider);
else
return arg.ToString();
}
#endregion
#region Helpers
/// <summary>
/// Returns day number with two character suffix text for the
/// day number component in the given date value
/// </summary>
/// <param name="date">Date</param>
/// <returns>String of day number including suffix (1st, 2nd, 3rd, 4th etc.)</returns>
private static string FormatDayNumberSuffix(DateTime date)
{
if (date == null)
throw new ArgumentNullException(nameof(date));
return string.Format(CultureInfo.InvariantCulture, "{0:dd}{1}",
date, GetDayNumberSuffix(date));
}
/// <summary>
/// Returns just the two character suffix text for the
/// day number component in the given date value
/// </summary>
/// <param name="date">Date</param>
/// <returns>String of day number suffix (st, nd, rd or th)</returns>
private static string GetDayNumberSuffix(DateTime date)
{
if (date == null)
throw new ArgumentNullException(nameof(date));
int day = date.Day;
switch (day)
{
case 1:
case 21:
case 31:
return "st";
case 2:
case 22:
return "nd";
case 3:
case 23:
return "rd";
default:
return "th";
}
}
#endregion
}
}
Sometimes you need to change a value for a specific platform and this value is a Double, for example. I spent a couple of minutes to find a working code.
<Label>
<Label.TranslationY>
<OnPlatform x:TypeArguments="x:Double" Android="-10" />
</Label.TranslationY>
</Label>
Happy coding!
Apple introduced with iOS 11 a new UI in particular for larger titles: if you open your email, you see at the top a large title. That sit in the Navigation Bar and can be scrolled away when more space is needed. We can enable large titles with a renderer.
For this example, I only created a new project and added the following renderer in the iOS project under Renderers folder. You can easily add to all your solution the following renderer in your iOS project:
using System;
using YourProject.iOS.Renderers;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(NavigationPage),
typeof(CustomNavigationRenderer))]
namespace YourProject.iOS.Renderers
{
public class CustomNavigationRenderer : NavigationRenderer
{
protected override void OnElementChanged(
VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
// Enables iOS 11 new Large Titles system-wide
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
// Enable Large Titles
NavigationBar.PrefersLargeTitles = true;
// Adopt same TextAttributes as for normal titles
// beacuse Xamarin.Forms NavigationPage
// does not have a dedicated property for this yet
UINavigationBar.Appearance.LargeTitleTextAttributes =
new UIStringAttributes {
ForegroundColor =
(Element as NavigationPage)?.
BarTextColor.ToUIColor() };
}
}
}
}
Happy coding!