Microsoft Orleans — Dependency Injection
Tags: dotnetcore, microsoftorleans, dependencyinjection, orleans
Published: 2018-11-14 14:43:10

---
title: Microsoft Orleans — Dependency Injection
published: true
tags: dotnet-core,microsoft-orleans,dependency-injection,orleans
canonical_url: https://medium.com/@kritner/microsoft-orleans-dependency-injection-6379d52a7169
series: Microsoft Orleans
---

### Microsoft Orleans — Dependency Injection

![](https://cdn-images-1.medium.com/proxy/0*JnJHfNGV4tkv8UPw.png)

Dependency Injection is an important part of writing loosely coupled, easily tested code. I’ve written a bit about it before, but not in the context of Microsoft Orleans.

Microsoft Orleans, like most (all?) applications, can make use of dependency injection. How do we do it in Orleans? Luckily, it is accomplished in a very similar manner to what you should already be used to when working with .net core!

If you aren’t familiar with .net core DI, a quick sample:

```cs
public interface IStuffDoer
{
 void DoStuff();
}

public class StuffDoer : IStuffDoer
{
 public void DoStuff()
 {
  Console.WriteLine("Stuff has been done");
 }
}
```

Within (generally) your Startup.cs or thereabouts:

```cs
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
 
 // Register services for DI
 services.AddSingleton<IStuffDoer, StuffDoer>();
}
```

And that’s pretty much all there is to it (as it relates to a MVC/WebApi site anyway). When instances of `IStuffDoer` are needed in class constructors, an instance is injected into the class — in this case the same instance, since we registered it as a singleton. You can read more about dependency injection here:

[Dependency injection in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1)

#### How do we apply this to Orleans?

![](https://cdn-images-1.medium.com/max/1024/0*nuH6GgCOQHGVz8Mv)<figcaption>Photo by <a href="https://unsplash.com/@sarabakhshi?utm_source=medium&amp;utm_medium=referral">Sara Bakhshi</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption>

We can demonstrate this dependency injection concept in Orleans by building a new `IOrleansFunction` of course! Note that this functionality was created for my Orleans series in:

[Updating Orleans Project to be more ready for new Orleans Examples!](https://dev.to/kritner/updating-orleans-project-to-be-more-ready-for-new-orleans-examples-41n2)

First, let’s start with our non grain related code — the stuff that we’ll be using and registering with the IOC container.

An email sending interface:

```cs
public interface IEmailSender
{
 Task SendEmailAsync(string from, string[] to, string subject, string body);
}
```

and an implementation:

```cs
public class FakeEmailSender : IEmailSender
{
 private readonly ILogger<FakeEmailSender> _logger;

 public FakeEmailSender(ILogger<FakeEmailSender> logger)
 {
  _logger = logger;
 }

 /// <summary>
 /// Pretend this actually sends an email.
 /// </summary>
 /// <param name="from"></param>
 /// <param name="to"></param>
 /// <param name="subject"></param>
 /// <param name="body"></param>
 /// <returns></returns>
 public Task SendEmailAsync(string from, string[] to, string subject, string body)
 {
  var emailBuilder = new StringBuilder();
  emailBuilder.Append("Sending new Email...");
  emailBuilder.AppendLine();
  emailBuilder.Append($"From: {from}");
  emailBuilder.Append($"To: {string.Join(", ", to)}");
  emailBuilder.Append($"Subject: {subject}");
  emailBuilder.Append($"Body: {Environment.NewLine}{body}");

  _logger.LogInformation(emailBuilder.ToString());

  return Task.CompletedTask;
 }
}
```

We can register this `FakeEmailSender` in our `ISiloHostBuilder`. I use a little helper class to keep all my DI registration in its own area, separate from the ISiloHostBuilder.

Helper class:

```cs
public static class DependencyInjectionHelper
{
 public static void IocContainerRegistration(IServiceCollection serviceCollection)
 {
  serviceCollection.AddSingleton<IEmailSender, FakeEmailSender>();
 }
}
```

Call the helper class from the `ISiloHostBuilder`:

```cs
.ConfigureServices(DependencyInjectionHelper.IocContainerRegistration)
```

The entire `ISloHostBuilder` method now looks like:

```cs
private static async Task<ISiloHost> StartSilo()
{
 // define the cluster configuration
 var builder = new SiloHostBuilder()
  .UseLocalhostClustering()
  .Configure<ClusterOptions>(options =>
  {
   options.ClusterId = "dev";
   options.ServiceId = "HelloWorldApp";
  })
  .Configure<EndpointOptions>(options => options.AdvertisedIPAddress = IPAddress.Loopback)
  .AddMemoryGrainStorage(Constants.OrleansMemoryProvider)
  .ConfigureApplicationParts(parts =>
  {
   parts.AddApplicationPart(typeof(IGrainMarker).Assembly).WithReferences();
  })
       .ConfigureServices(DependencyInjectionHelper.IocContainerRegistration)
  .UseDashboard(options => { })
  .ConfigureLogging(logging => logging.AddConsole());

 var host = builder.Build();
 await host.StartAsync();
 return host;
}
```

#### Now that we have a registered service, let’s use it in a grain!

I’m just going to put into place a grain that sends out an email, using out new dependency injected service. Yes, we could just write the email sending within the grain itself, but I wanted to show off dependency injection Additionally, this way we can swap in a “real” implementation w/o the (small amount of) boilerplate involved with standing up a grain.

New Grain Interface:

```cs
public interface IEmailSenderGrain : IGrainWithGuidKey, IGrainInterfaceMarker
{
 Task SendEmail(string from, string[] to, string subject, string body);
}
```

And implementation:

```cs
public class EmailSenderGrain : Grain, IEmailSenderGrain, IGrainMarker
{
 private readonly IEmailSender _emailSender;

 public EmailSenderGrain(IEmailSender emailSender)
 {
  _emailSender = emailSender;
 }

 public async Task SendEmail(string from, string[] to, string subject, string body)
 {
  await _emailSender.SendEmailAsync(from, to, subject, body);
 }
}
```

In the above Grain, we’re taking in an instance of an `IEmailSender` for use within the actual implementation of the `IEmailSenderGrain` contract. With the setup we did in the `ISiloHostBuilder`, the `FakeEmailSender` is passed into the class automatically.

#### Wire up the new grain call in the console app

Now we need to wire up the new grain call into our console app menu — luckily this is simple due to the refactor pointed out in the above blog post.

Add a new class that implements `IOrleansFunction`:

```cs
public class DependencyInjectionEmailService : IOrleansFunction
{
 public string Description => "Shows off dependency injection within a grain implementation.";

 public async Task PerformFunction(IClusterClient clusterClient)
 {
  var grain = clusterClient.GetGrain<IEmailSenderGrain>(Guid.NewGuid());
  Console.WriteLine("Sending out a totally legit email using whatever service is registered with the IEmailSender on the SiloHost");

  var body = @"
     .-'---`-.
   ,' `.
   | 
   | 
    _ 
   , _ ,'-,/-)
   ( *  ,' ,' ,'-)
    `._,) -',-')
      / ''/
    ) / /
      / ,'-'
  ";

  await grain.SendEmail(
   "someDude@somePlace.com", 
   new[] { "someOtherDude@someOtherPlace.com" }, 
   "ayyy lmao",
   body
  );
 }
}
```

#### Ship it!

Let’s see what this looks like running.

- Build
- `dotnet run` the SiloHost
- `dotnet run` the client
- select whatever option it ends up being for the new grain

Output:

![](https://cdn-images-1.medium.com/max/1024/1*Ugf8DPMcgQKHI6r00LuQPQ.png)

Note in the above that the “email” is being shown in the Orleans console, as the `FakeEmailSender` told it to just “log”, and from the context of where the function is running, it hits the Orleans log, rather than the menu-ed console app.

That’s all there is to it!

Code at this point is in this release on the GitHub repository:

[Kritner-Blogs/OrleansGettingStarted](https://github.com/Kritner-Blogs/OrleansGettingStarted/releases/tag/v0.40)

Related:

- [Getting Started with Microsoft Orleans](https://medium.com/@kritner/getting-started-with-microsoft-orleans-882cdac4307f?source=friends_link&sk=1fc3451d71a19dcb49f2c8bbeb6b079e)
- [Microsoft Orleans — Reusing Grains and Grain State](https://medium.com/@kritner/microsoft-orleans-reusing-grains-and-grain-state-136977facd42?source=friends_link&sk=f19cfa3f17665c3d700bfe0df56e27a9)
- [Microsoft Orleans — Reporting Dashboard](https://medium.com/@kritner/microsoft-orleans-reporting-dashboard-16465d255199)
- [Using polymorphism to update Orleans Project to be ready for new Orleans Examples!](https://medium.com/@kritner/updating-orleans-project-to-be-more-ready-for-new-orleans-examples-2105b29a46fd?source=friends_link&sk=61d1f591e5b5c498688439db50ad310e)
- Code as of end of blog post — [v0.40](https://github.com/Kritner-Blogs/OrleansGettingStarted/releases/tag/v0.40)
- [Microsoft Docs — Dependency Injection](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1)