Microsoft Orleans-Dependency Injection
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 — Dependency Injection
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:
1 |
|
Within (generally) your Startup.cs or thereabouts:
1 |
|
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
How do we apply this to Orleans?
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!
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:
1 |
|
and an implementation:
1 |
|
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:
1 |
|
Call the helper class from the ISiloHostBuilder
:
1 |
|
The entire ISloHostBuilder
method now looks like:
1 |
|
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:
1 |
|
And implementation:
1 |
|
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
:
1 |
|
Ship it!
Let’s see what this looks like running.
- Build
dotnet run
the SiloHostdotnet run
the client- select whatever option it ends up being for the new grain
Output:
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
Related:
- Getting Started with Microsoft Orleans
- Microsoft Orleans — Reusing Grains and Grain State
- Using polymorphism to update Orleans Project to be ready for new Orleans Examples!
- Microsoft Orleans — Reporting Dashboard
- Microsoft Orleans — Code Generation Issue
- Code as of end of blog post — v0.40
- Microsoft Docs — Dependency Injection
Microsoft Orleans-Dependency Injection
https://blog.kritner.com/2018/11/14/Microsoft-Orleans-Dependency-Injection/