I referenced several documents but I need correct implementation to do it correctly.
References
Unity to Worker Role: https://alexandrebrisebois.wordpress.com/2013/04/14/building-windows-azure-services-without-compromising-testability/
SimpleInjector for Console app: http://simpleinjector.readthedocs.io/en/latest/consoleintegration.html
My questions
Reference-1, Unity
use using (var uc = new UnityContainer()){...}
but SimpleInjector has ThreadScopedLifestyle
or AsyncScopedLifestyle
. Which one do I use?
Reference-2 has static Main
class, static readonly Container
, and static contructor
. Do I define static Container
for Worker role? what about static constructor
for dependency registration?
I implemented as below My Implementation section. Is this code implemented correctly?
Reference Code
Reference 1;
static class Program
{
static readonly Container container;
static Program()
{
container = new Container();
container.Register<IUserRepository, SqlUserRepository>();
container.Register<MyRootType>();
container.Verify();
}
static void Main()
{
var service = container.GetInstance<MyRootType>();
service.DoSomething();
}
}
Reference 2;
public class WorkerRole : RoleEntryPoint
{
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("Worker entry point called", "Information");
using (var uc = new UnityContainer())
{
uc.RegisterType<ILogger, TableStorageLogger>();
uc.RegisterType<IEnumerable<IMessageHandler>, IMessageHandler[]>();
var processor = uc.Resolve<MessageProcessor>();
while (true)
{
processor.Process();
Thread.Sleep(10000);
Trace.WriteLine("Working", "Information");
}
}
}
My Implementation
I thought (1) Container
could be enough to be static
, (2) OnStart
is good place to register services, and (3) I intended service instances are created and disposed per each loop.
public class WorkerRole : RoleEntryPoint
{
static readonly Container container = new Container();
public override void Run()
{
while (true)
{
using (ThreadScopedLifestyle.BeginScope(container))
{
var service = container.GetInstance<SomeService>();
service.DoSomething();
}
}
}
public override bool OnStart(){
// define.
container.Register<SomeService>();
container.Register<ProcessRecorderSetting>();
container.Verify();
}
}
Note: I don't know above code is working.
Reference-1, Unity use using (var uc = new UnityContainer()){...} but SimpleInjector has ThreadScopedLifestyle or AsyncScopedLifestyle. Which one do I use?
If I'm not mistaken, an Azure Worker Role is a short-lived application, that gets kicked off to do one simple thing and than dies quickly, just like you would with a Console Application.
Considering DI, this makes the development of a Worker Role very similar to that of a Console application. This means:
What this means is that, since the application is single-threaded and short-lived, there is no need to use a scoped lifestyle (such as ThreadScopedLifestyle
or AsyncScopedLifestyle
). Instead you could easily register all dependencies as singleton, resolve the root, call its method, and dispose the container.
If however, your application lives for a long time, and goes on in an endless loop, you typically want to simulate the notion of a 'request'. This typically means that every loop is a request, and during that request you resolve from the container. Note that you only need a scoped lifestyle if you actually have scoped registrations. If not, you don't have to wrap the request in a scope. If you have scoped registrations, you'll have to wrap each request in a scope, just as you did in your example.
Reference-2 has static Main class, static readonly Container, and static contructor. Do I define static Container for Worker role? what about static constructor for dependency registration?
Although static constructors give thread-safety and singleton behavior for free, they do however complicate debugging in case an exception is thrown, since the real error is wrapped in a TypeInitializationException
. Your cctor however does make it easy to initialize your static Container
field. It's fine to have the Container
in a static field.
However, since these types of applications are really small with only a small set of Dependencies, do container to not use a DI Container at all. Instead use Pure DI. This might sound like a strange advice from someone who develops and maintains a DI Container, but I found it more practical to use Pure DI for small applications, especially when everything your register is singleton anyway. The advantages are: