Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any benefit (semantic or other) to using a static method that calls a constructor?

I just updated Visual Studio 2013 and I noticed that in the project template for an MVC application the ApplicationDbContext class now has a static method that just calls the constructor:

public static ApplicationDbContext Create()
{
    return new ApplicationDbContext();
}

This seems like clutter to me but I imagine that there is some semantic reason that I should now start using ApplicationDbContext.Create() instead of new ApplicationDbContext(). Are there any benefits to doing so?

like image 795
regularmike Avatar asked Jun 20 '14 01:06

regularmike


People also ask

What is the benefit to use static factory in place of constructor?

Static factory methods can encapsulate all the logic required for pre-constructing fully initialized instances, so they can be used for moving this additional logic out of constructors.

Can we call static method from constructor?

A class or struct can only have one static constructor. Static constructors cannot be inherited or overloaded. A static constructor cannot be called directly and is only meant to be called by the common language runtime (CLR).

Can a static class have constructor?

Static classes cannot contain an instance constructor. However, they can contain a static constructor. Non-static classes should also define a static constructor if the class contains static members that require non-trivial initialization.

When should you use a static method?

Static methods are usually preferred when: All instance methods should share a specific piece of code (although you could still have an instance method for that). You want to call method without having to create an instance of that class. You must make sure that the utility class is never changed.


1 Answers

Actually. yes.

In your specific case, wrapping it thusly allows you to quickly start bolting on logic, such as making the ApplicationDbContext and singleton or handling an exception in a common way for the whole application. Since a constructor cannot return null, this can be very important to be able to catch an exception and return null.

Tuple.Create is the prime example of generic inference, which does not work with Constructors. This allows you say

Tuple.Create(Item1, Item2.. ItemN);

And the let the compiler infer types, rather than

new Tuple<T1, T2...Tn>(Item1, Item2...ItemN);

Which is more verbose, and takes a bit more work if you want to switch out one of those types.

There is also the case of Anonymous types, which cannot be specified explicitly and thus cannot be used in new statements. I have specifically had occasion where, while searching assemblies for a specific Attribute to link a command structure for, I wanted to make an enumerable (a Queue, in this case) out of an anonymous type during the search to pair class references with their constructor and string arguments, rather than looking these up every time they're needed. Since I can again use Generic inference in a method, I was able to wrap the constructor in an extension method and get the job done.

There are also cases for singleton patterns, wherein you want the "GetInstance" method to usually create a value, or get one if it exists. May not qualify since it does slightly more than wrap a constructor.

In addition, there are plenty of cases where you may want to control implementation procedures, such as forcing them onto other threads, logging them in a database to be undone later, or bolting on a permissions system, all of which can be done by making a constructor wrapper and adding a few more lines of logic, and then privatizing the constructor to avoid it being called directly.

There are also cases where I've created a factory method which delegates to known children in order to provide a different implementation of a returned interface or abstract based on provided parameters. This has the added benefit of being able to hide the implementing classes - the Type class and IEnumerable interface make use of this pattern.

like image 162
David Avatar answered Oct 14 '22 09:10

David