Say I have the class below
public class MyClass {
private readonly NinjaObject _myNinja;
MyClass(NinjaFactory ninjaFactory) {
_myNinja = ninjaFactory.CreateNinjaButItTakesTime();
}
public void NinjaAttack() {
_myNinja.Attack();
}
}
Now, the constructor should do everything to initialise the class and get it ready for use by the application, i.e., create the Ninja and have it ready to attack when called to do so. It's also a good idea to have your constructor perform their actions quickly. However, this may not be possible if the process of creating a Ninja takes a long time. I presume you could create the Ninja asynchronously through some kind of static factory method, but then you run the risk (at least theoretically) of the Ninja not being ready (i.e. a null object) to attack when called to do so by the application.
When you have fields of a class that are critical to how that class operates but can take a long time to construct, what is the best pattern to adopt in creating them? Keep it synchronous in the constructor, or apply some kind of asynchronous pattern?
I presume you could create the Ninja asynchronously through some kind of static factory method, but then you run the risk (at least theoretically) of the Ninja not being ready (i.e. a null object) to attack when called to do so by the application.
Well, this is where an async static factory method comes in handy:
public class MyClass
{
private readonly Ninja ninja;
private MyClass(Ninja ninja)
{
this.ninja = ninja;
}
public static async Task<MyClass> Create()
{
// Or however you create a ninja - ideally properly asynchronous
var ninja = await Ninja.Create();
return new MyClass(ninja);
}
public void NinjaAttack() => ninja.Attack();
}
You can't avoid it taking a long time - but you can make the creation asynchronous by leaving the constructor call right to the end. This basically works around the restriction that constructors can't be asynchronous.
An alternative - but a dangerous one - would be to start the task creating the ninja and pass that into the constructor, but use the result of the task later:
public class MyClass
{
private readonly Task<Ninja> ninjaTask;
public MyClass(Task<Ninja> ninjaTask)
{
this.ninjaTask = ninjaTask;
}
public void NinjaAttack() => ninjaTask.Result.Attack();
}
That's dangerous because using Task<T>.Result can deadlock in some cases, if the task needs to do more work in the current synchronization context before completing. You could avoid that by making your NinjaAttack method asynchronous instead:
public class MyClass
{
private readonly Task<Ninja> ninjaTask;
public MyClass(Task<Ninja> ninjaTask)
{
this.ninjaTask = ninjaTask;
}
public async Task NinjaAttack() => (await ninjaTask).Attack();
}
Depending on your context, you might want to use await ninjaTask.ConfigureAwait(false).
Related
I have a parent-child class structure where parent class in constructor creates instance of the child class and use one of child class async methods with .Result approach.
public class ParentClass
{
private readonly ChildClass _childClass;
public ParentClass()
{
_childClass = new ChildClass();
bool result = _childClass.GetSomething().Result;
}
}
public class ChildClass
{
public ChildClass()
{
}
public async Task<bool> GetSomething()
{
return await Task.FromResult<bool>(false);
}
}
My goal is to remove .Result and change it with normal await keyword. I can create static async method, there create instance of the child class, later call constructor and pass instance.
public class ParentClass2
{
private readonly ChildClass _childClass;
private ParentClass2(ChildClass childClass, bool result)
{
_childClass = childClass;
}
public static async Task<ParentClass2> GetInstance()
{
ChildClass childClass = new ChildClass();
bool result = await childClass.GetSomething();
return new ParentClass2(childClass, result);
}
}
But then I have 2 problems:
The more parents of parents [..of parents] I have - the more code I have to modify in a same way.
Highest level classes use DI. And with async I can't do this
services.AddScoped<ParentClass2>(async p =>
{
var instance = await ParentClass2.GetInstance();
return instance;
});
Any suggestions?
When you deal with dependency injection and asynchronous initialization, you have to make compromises.
In general, I approach this one of two ways.
If the asynchronous initialization is done once at startup, you can extract the asynchronous call out before the DI is set up, run it synchronously, and inject the results into the constructors for your types at DI setup.
The other option is to essentially do the asynchronous initialization on-demand whenever any other method is called. The constructor could start it, and every method would (asynchronously) wait for the initialization to complete. This does have the side effect that the entire API has to be asynchronous. Either that, or you change the DI type to be an asynchronous factory which then asynchronously creates the type with your actual API.
I have the following method, which is to add product using the injected service! It is called inside a static calls hence it is static!
public static async Task AddNewProducts(Guid shopId)
{
var productAService = IoC.Services.GetService<IProductAService>();
var added = await productAService.AddProduct(shopId);
}
It works fine but I need to make it generic so that I can use different services with it.
Something like this!
public static async Task AddNewProducts<T>(Guid shopId)
where T : IProductAService, IProductBService
{
var productService = IoC.Services.GetService<T>();
var added = await productService.AddProduct(shopId);
}
However the second methods complains that the AddProduct method is ambiguous, not sure how I can make sure it is calling the right method from the related service!
Your 2 services need a common interface
public interface IProductService
{
void AddProduct(Guid shopId);
}
public interface IProductAService : IProductService
{
//specifics to service A
}
public interface IProductBService : IProductService
{
//specifics to service B
}
Then your static, generic method just constrains to the shared interface
public static async Task AddNewProducts<TProductService>(Guid shopId)
where TProductService : IProductService
{
var productService = IoC.Services.GetService<TProductService>();
await productService.AddProduct(shopId);
}
This gets slippery very quickly. You hinted that AddProduct is not a void, but returns a particular object. That's fine, you can make IProductService itself generic
public interface IProductService<TProduct>
{
TProduct AddProduct(Guid shopId);
}
public interface IProductAService : IProductService<ProductA>
{
//specifics to service A
}
public interface IProductBService : IProductService<ProductB>
{
//specifics to service B
}
But now you need to also pass the product type to the generic method, as I said - it gets slippery quickly (but maybe it'll do!)
public static async Task AddNewProducts<TProductService, TProduct>(Guid shopId)
where TProductService : IProductService<TProduct>
{
var productService = IoC.Services.GetService<TProductService<TProduct>>();
var added = await productService.AddProduct(shopId);
// Note "added" is of type TProduct
}
I call this situation "Generic hell". You are better of rethinking your design!
public static async Task AddNewProducts<T>(Guid shopId) where T : IProductAService, IProductBService
The problem with that line is that you're requiring T to implement both interfaces at once, not just one of them. You haven't even gotten to the errors that will spring up when you try to call this function, because presumably your class won't implement both.
Which leads me to question why you think you need to constrain your T like this. The only usage of T is to call Services.GetService<T>(), so the only constraint on it should be exactly the constraints that function requires, which are definitely not your two interfaces.
UPDATED:
I read here https://learn.microsoft.com/en-us/previous-versions/msp-n-p/ff650316(v=pandp.10)?redirectedfrom=MSDN about 3 different ways of implementing the singleton in c#. I'm particularly interested in understanding this line:
Because the instance is created inside the Instance property method,
the class can exercise additional functionality (for example,
instantiating a subclass), even though it may introduce unwelcome
dependencies.
I understand that although lazy instantiation is not thread safe, still because it only instantiates it on demand it thus avoids instantiation every time the class is loaded. I also notice that in Lazy-instantiation I can use a non-default constructor and pass parameters whereas in Static.. But say I didn't mind it's instantiated every time it's loaded and I'm happy with a default constructor, why would I choose Lazy over static or even over the multi-threaded approach? Is there something Lazy can get me that static and multi-threaded can't? Can one be sub classed and the other not?
Also, that page seems to be saying that static initialisation is also thread-safe? Why is that? And why are they proceeding to a third multi-threaded approach if the latter is fine too?
Because the Singleton instance is referenced by a private static
member variable, the instantiation does not occur until the class is
first referenced by a call to the Instance property. This solution
therefore implements a form of the lazy instantiation property, as in
the Design Patterns form of Singleton.
(Nonetheless, I don't understand the first part of this para: if instantiation here also occurs only once as they say in a couple of paragraphs before:
"In this strategy, the instance is created the first time any member
of the class is referenced."
how is it different than the lazy approach?)
So to summarise, my question is what DOES static come to cure over the first, lazy approach and why would I still choose Lazy other than the reason that it allows me to use a none-default constructor?
Whilst I'm at it:
Consider the following two pairs of examples of Lazy vs Static, my question is, within each pair, how are they different from one another? I can see in one, the 'get' is nested within the GetInstance/Instance method but does it make any difference?
public class LazySingleton
{
private static LazySingleton _LSInstance;
private LazySingleton() { }
public static LazySingleton GetInstnace
{
get{
if (_LSInstance == null)
{
_LSInstance = new LazySingleton();
}
return _LSInstance;
}
}
}
public class LazySingleton
{
private static LazySingleton _LSInstance { get; set; }
private LazySingleton() { }
public static LazySingleton GetInstnace() {
if (_LSInstance == null)
_LSInstance = new LazySingleton();
return _LSInstance;
}
}
=======================================================
public class Singleton
{
private Singleton()
{
}
private static Singleton _LSInstance = new Singleton();
public static Singleton GetInstnace
{
get{
return _LSInstance;
}
}
}
public class Singleton
{
private Singleton() { }
private static Singleton _LSInstance = new Singleton();
public static Singleton GetInstnace()
{
return _LSInstance;
}
}
I'd really appreciate a response that can clarify this for me, thank you!
From your code, I can tell 1 difference. Let's assume to instantiate your instance, you need to wait for the system to load some data. And you're not sure the data is available when system starts (maybe few seconds later, it's available). And your service is only needed in some pages. With lazy load, you don't have any problem, since you don't use the service until some time later. But with static instantiating, you will have a problem.
A Quick Note
The code in this post is built on top of a in-house built DirectX-11 engine which means it follows the strict pattern of:
Initialize
while (Running) {
Update
Render
}
However, do not let this deter you as the problem is not related to the DirectX code but instead static classes and methods.
Overview
I have a class called RenderObject which contains a method called Initialize. This method is responsible for building the object's mesh, assigning textures, shaders, and more.
public class RenderObject {
public virtual void Initialize() { }
}
I also have a few static classes that hold reusable assets such as common textures, shaders, models, and meshes. This way I don't have to reload them later. All of these static classes also contain a method called Initialize which is responsible for creating these reusable assets. For this question I will limit this to just the Textures class.
public static class Textures {
public static Texture2D Dirt { get; private set; }
public static Texture2D Grass { get; private set; }
public static void Initialize() {
Dirt = new Texture2D(...);
Grass = new Texture2D(...);
}
}
Finally, I have a class called LoadingSystem which is responsible for loading reusable assets and initializing objects. I initialize this class inside of the Initialize method of my engine, and then call the class' Update method in the Update method of the engine respectively. The LoadingSystem's Update method is responsible for loading and initializing objects using a Queue which is useful for supplying smooth visual feedback.
public class LoadingSystem {
public bool Loading { get; private set; } = true;
private Queue<RenderObject> objectsToRender;
public void AddForLoad(RenderObject obj) => objectsToRender.Enqueue(obj);
public void Update() {
if (objectsToRender.Count > 0) {
RenderObject obj = objectsToLoad.Dequeue();
obj.Initialize();
} else Loading = false;
}
}
The Problem
I would like to call the method Initialize on these static classes with the same process used for the RenderObject queue. Currently I'm forced to do:
CurrentMessage = "Loading Textures";
Render();
Present();
Textures.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
CurrentMessage = "Loading Shaders";
Render();
Present();
Shaders.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
CurrentMessage = "Loading Models";
Render();
Present();
Models.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
I've slimmed it down to a method that handles the repetitive setting of the message, and calls to Render and Present but this is still tedious and it should go through the Update method once per object to remain consistent with the rest of the code.
My Thoughts
I understand that a static class cannot inherit from a class or implement an interface so I am wondering if there is a way to provide a static class and call its Initialize method in a similar manner; even if this means creating a separate method to accomplish it.
I have currently considered two options:
Load static classes individually.
Convert static classes to instance classes and call them with the queue.
The problem with the first option is that I have 12 static classes and would have to update progress and feedback messages, raise events, and re-render the scene for each one.
The problem with the second option is that these static classes only contain static properties and thus by definition should be static as there is no need to ever inherit from them or create an instance of them.
The Question
Is there a way to call a common method across multiple static classes?
Perhaps a way to call the method if it exists with generic types like object or T?
Perhaps the dynamic type may work (though you can't create an instance of static classes)?
I have currently considered two options:
Load static classes individually.
Convert static classes to instance classes and call them with the queue.
A third compromise approach relates to your second idea above, but uses a design pattern known as the Singleton Pattern. Like static classes, there can only be one of them in your process and everyone gets that same thing, however unlike static classes, Singletons can implement interfaces or even descend from other classes.
For this example, I will use the interface approach.
public interface IInitializable
{
void Initialize();
}
All the interface does is to enforce that its implementer has an Initialize method.
My next step is to create a Singleton class. There are a couple of rules to implement the Singleton pattern. Your class must be sealed. Its constructor must be private. It must have a static method or property to return the single instance. That method/property must be threadsafe.
I have used Lazy to do the heavy lifting for me
public sealed class Foo : IInitializable
{
public void Initialize()
{
// Initialize my foo
}
private Foo()
{
}
private static Lazy<Foo> fooLazy = new Lazy<Foo>(() => new Foo());
public static Foo Instance => fooLazy.Value;
}
There are some minor differences to what you were doing with static classes. If Foo was a static class, you would call Foo.Initialize(); As it is Singleton, you would call Foo.Instance.Initialize();
Any other methods or properties would most likely be non-static.
Pulling it all together, you could write code like this. Your queue does not need to know about the classes it holds. You don't actually care. You only want to know that it has the Initialize() method
public class YourClass
{
private Queue<IInitializable> objectsToLoad = new Queue<IInitializable>();
public void Enqueue(IInitializable obj)
{
this.objectsToLoad.Enqueue(obj);
}
public void LoadOrUpdate()
{
// Update Method
if (objectsToLoad.Count > 0)
{
IInitializable obj = objectsToLoad.Dequeue();
obj.Initialize();
}
else
{
// Loading complete.
}
}
}
This class could then be used like this
YourClass yourClass = new YourClass();
yourClass.Enqueue(Foo.Instance);
yourClass.LoadOrUpdate();
Though I hope there is a much better and more detailed answer than this; I've come up with a basic solution. I created a separate Queue<Type> where I add the static classes. I then call their Initialize method with the following:
Type t = typesToInit.Dequeue();
t.GetMethod("Initialize").Invoke(null, new object[] { 0 });
This works well and is rather clean, but I can't help but wonder if there is a better way to do this?
I am working on a MVC3 application in which I would like to handle some code blocks asynchronously. These code blocks need to perform some db operations and they need access to my DAL repositories which are initiated trough my dependency injection setup. I have set the lifetime of the repository to an "instance per http request" lifetime and I am looking for a way to extend that lifetime for the async operation.
public class AsyncController : Controller
{
private readonly ICommandBus commandBus;
private readonly IObjectRepository objectRepository;
public ActionResult DoThings()
{
DoThingsAsync();
return View();
}
private delegate void DoThingsDelegate();
private void DoThingsAsync()
{
var handler = new DoThingsDelegate(DoThingsNow);
handler.BeginInvoke(null, null);
}
private void DoThingsNow()
{
var objects = objectRepository.getAll();
foreach (Thing thing in objects)
{
thing.modifiedOn = DateTime.Now;
objectRepository.Update(thing);
}
}
}
The objectRepository is initiated for the lifetime of the request and I would like to skip the garbage collection for this object for one method in one controller only. I have tried to pass the repository as a parameter to the method and the delegate but that did not extend its lifetime.
When starting a new thread, it is wise to let the Container compose a totally new object graph for you. When you reuse dependencies that are created in the context of a HTTP request (or thread context or what have you), this can result in race conditions and other sort of failures and strange behavior.
This of course doesn’t have to be the case when you know that those dependencies are thread-safe (or created with a per-request lifetime and are not used by the request after triggering the async operation), but this is not something a consumer of these dependencies should know or should depend on, because it is the responsibility of the part of the application that wires everything together (The Composition Root). Doing this, would also make it harder to change that dependency configuration later on.
Instead, you should refactor your DoThings method into its own class and let your Controller depend on some sort of IDoThings interface. This way you can postpone the decision about handling things asynchronously until the moment you wire everything together. When reusing that logic in another type of application (Windows Service for instance), it even allows you to change the way this operation is executed asynchronously (or simply execute it synchronously).
To go even one step further, the actual DoThings business logic and the part that executes that logic asynchronously are two different concerns: two separate responsibilities. You should separate them into different classes.
Here's an example of what I advise you to do:
Define an interface:
public interface IDoThings
{
void DoThings();
}
Let your Controller depend on that interface:
public class SomeController : Controller
{
private readonly IDoThings thingsDoer;
public SomeController(IDoThings thingsDoer)
{
this.thingsDoer = thingsDoer;
}
public ActionResult DoThings()
{
this.thingsDoer.DoThings();
return View();
}
}
Define an implementation that contains the business logic:
public class DoingThings : IDoThings
{
private readonly ICommandBus commandBus;
private readonly IObjectRepository objectRepository;
public DoingThings(ICommandBus commandBus,
IObjectRepository objectRepository)
{
this.commandBus = commandBus;
this.objectRepository = objectRepository;
}
public void DoThings()
{
var objects = objectRepository.getAll();
foreach (Thing thing in objects)
{
thing.modifiedOn = DateTime.Now;
objectRepository.Update(thing);
}
}
}
Define a proxy that knows how to handle a DoingThings asynchronously:
public class DoingThingsAsync : IDoThings
{
private readonly Container container;
public DoingThingsAsync(Container container)
{
this.container = container;
}
public void DoThings()
{
Action handler = () => DoThingsNow();
handler.BeginInvoke(null, null);
}
private void DoThingsNow()
{
// Here we run in a new thread and HERE we ask
// the container for a new DoingThings instance.
// This way we will be sure that all its
// dependencies are safe to use. Never move
// dependencies from thread to thread.
IDoThings doer =
this.container.GetInstance<DoingThings>();
doer.DoThings();
}
}
Now, instead of injecting a DoingThings into the SomeController, you inject a DoingThingsAsync into the controller. The controller does not know whether the operation is executed synchronously or not, and it doesn't care. Besides that, this way you are also separating your business logic from your presentation logic, which is important for lots of good reasons.
You might want to consider using the command pattern as basis around business operations that mutate state (if you're not already using such a thing, considering the ICommandBus interface). Take for instance a look at this article. With this pattern you can more easily configure certain commands to run asynchronously or batch them to an external transactional queue, for later processing, without having to change any of the consumers of those commands.