Im currently trying to build a Fluent Interface for a ServiceLocator. To ensure that each the developer can easily setup 1-to-n mappings
I'd like something like this
ServiceLocator.Instance.For<IFoo>(Use<Foo>(), Use<FooBar>());
Singleton is workin fine... the methodsignature for the For method looks like this
public void For<TInterface>(params type[] services)
{
// ...
}
So I was looking for something like a global method
C# has some global methods, all methods which are defined on System.Object. But when I create a new generic ExtensionMethod on System.Object, the method will not be visible.
public static class MyExtensions
{
public static void Use<T>(this Object instance)
{
// ..
}
}
MethodChaining would be the alternative, but this approach looks sexy :D
Has anyone an idea?
Well, actually when I create an extension method for Object, it is visible. As in,
public static class Extensions
{
public static void doStuff<T>(this T myObject)
{
}
}
class Program
{
static void Main(string[] args)
{
int a = 5;
a.doStuff();
string b = "aaa";
b.doStuff();
List<int> c = new List<int>() { 1, 2, 3, 10 };
c.doStuff();
Extensions.doStuff(c);
}
}
Did I misunderstand your question?
You need to add a using statement for the namespace containing your extension method in order for it to be visible. Adding extension methods to object is rarely a good idea.
EDIT:
Okay, now I understand what you're asking. In order to use an extension method you need an instance. You're asking for a static extension method on object (Equals and ReferenceEquals are static methods), and that's not possible. If you define an extension method on object, it will be available on all instances and I'm sure that's not what you want.
public static class ObjectExtensions
{
public static string TypeFullName(this object obj)
{
return obj.GetType().FullName;
}
}
static void Main(string[] args)
{
var obj = new object();
Console.WriteLine(obj.TypeFullName());
var s = "test";
Console.WriteLine(s.TypeFullName());
}
Service Locator is widely considered to be an anti-pattern. Also, a common registration interface is widely considered to be an unsolvable problem unless you are requiring use of a specific container.
Looking past these two questionable decisions, you can remove the need for the global method by defining overloads of For which accept multiple type arguments:
ServiceLocator.Instance.For<IFoo, Foo, FooBar>();
The For methods would look like this:
public void For<TInterface, TImplementation>()
public void For<TInterface, TImplementation1, TImplementation2>()
...
You have to define an overload for each type count, but it requires the minimal syntax and maximum amount of discoverability. For reference, the .NET Framework's Action and Func types support 9 type arguments.
After writing this out, though, I wonder if I misunderstood the question: why would you specify multiple implementations for the same interface? Wouldn't that lead to ambiguity when resolving IFoo?
Related
I have a class with several static methods that is being used in a CLR SQL stored procedure method. I ended up writing a wrapper with non-static methods that implements an interface of the methods I want.
I'm doing this so that I can write a unit test. However, the unit test is for a static method that also has another dependency that I can't figure out how to work around.
Note: CLR Stored Procedures need to be static.
public class MyHelperWrapper : IMyHelper
{
public void DoStuff(List<MyObject> list)
{
MyHelper.DoStuff(list); // Static method that sends data to database.
}
}
public class FakeMyHelperWrapper : IMyHelper
{
public void DoStuff(List<MyObject> list)
{
// don't do anything??
}
}
public class MyCLRClass
{
public static void My_Stored_Proc(string a, string b)
{
MyPrivateStaticMethod(a, b);
}
private static void MyPrivateStaticMethod(string a, string b)
{
List<MyObj> list = new List<MyObject>();
MyObject obj = new MyObject(a, b);
list.Add(obj);
MyHelperWrapper.DoStuff(list); // MyWrapper is wrapped around the static methods of the class MyHelper
}
private static string Format(string b)
{
// ... format ...
return bFormatted;
}
}
At the end of the day, I guess I really just need to test that the method creates a new object based on the parameters a and b and then adds it to a list.
My issues:
The method is void so what's the proper way to even test this? Just make sure no errors happen?
If I'm injecting fake classes (such as a fake MyHelperWrapper) then I'm basically bypassing a bunch of the code. This seems bad to me?
If I were to continue this route, how can I inject a fake class for MyObject? This seems kind of bad because then I'm not testing that the object is created how I expect.
Is there a better way? Maybe I have to refactor MyObject to use DI as well but this all seems kind of hacky just to test that an object is added to a list.
The way I resolved this was by injecting the dependency (that was causing the issue) into the constructor of MyObject.
I'm trying to refactor a method that parses through a file. To support files of arbitrary size, the method using a chunking approach with a fixed buffer.
public int Parse()
{
// Get the initial chunk of data
ReadNextChunk();
while (lengthOfDataInBuffer > 0)
{
[parse through contents of buffer]
if (buffer_is_about_to_underflow)
ReadNextChunk();
}
return result;
}
The pseudo code above is part of the only public non-static method in a class (other than the constructor). The class only exists to encapsulate the state that must be tracked while parsing through a file. Further, once this method has been called on the class, it can't/shouldn't be called again. So the usage pattern looks like this:
var obj = new MyClass(filenameToParse);
var result = obj.Parse();
// Never use 'obj' instance again after this.
This bugs me for some reason. I could make the MyClass constructor private, change Parse to a static method, and have the Parse method new up an instance of Parse scoped to the method. That would yield a usage pattern like the following:
var result = MyClass.Parse(filenameToParse);
MyClass isn't a static class though; I still have to create a local instance in the Parse method.
Since this class only has two methods; Parse and (private) ReadNextChunk, I'm wondering if it might not be cleaner to write Parse as a single static method by embedding the ReadNextChunk logic within Parse as an anonymous method. The rest of the state could be tracked as local variables instead of member variables.
Of course, I could accomplish something similar by making ReadNextChunk a static method, and then passing all of the context in, but I remember that anon methods had access to the outer scope.
Is this weird and ugly, or a reasonable approach?
This maybe suitable more to code review.
However, these are my comments about your design:
I don't think it will matter much about obj instance only used once. If you bugged with it, there are 2 ways to trick it:
Use of another method such as:
public int Parse()
{
var obj = new MyClass(filenameToParse);
return obj.Parse();
}
Make the MyClass implement IDisposable and wrap it in using statement. I don't recommend this since usually IDisposable has logic in their Dispose() method
I think it is better to make your MyClass accept parameter in Parse to Parse(string fileNameToParse). It will make MyClass as a service class, make it stateless, reusable and injectable.
Regarding impact to static class. First it add coupling between your consumer and MyClass. Sometimes if you want to test / unit test the consumer without using the MyClass parser, it will be hard / impossible to mock the MyClass into something you want.
All you need is a static parse method that creates an instance, much like what you suggest in your question
public class MyClass
{
// your existing code.... but make the members and constructor private.
public static int Parse(string filenameToParse)
{
return new MyClass(filenameToParse).Parse();
}
}
then
just use it like you suggest...
var result = MyClass.Parse(filenameToParse);
MyClass isn't a static class though; I still have to create a local
instance in the Parse method.
You don't need a static class to be able to leverage static methods. For example this works fine:
public class MyClass
{
public static string DoStuff(string input)
{
Console.WriteLine("Did stuff: " + input);
return "Did stuff";
}
}
public class Host
{
public void Main()
{
MyClass.DoStuff("something");
}
}
I want to, for example, add a method to integer (i.e., Int32), which will make me able to do the following:
int myInt = 32;
myInt.HelloWorld();
One can say, instead of insisting doing the above, you can write a method which takes an integer, HelloWorld(integer), like the following, more easily:
int myInt = 32;
HelloWorld(myInt);
However, I'm just curious whether it's possible or not. If true, is that a good programming practice to add some other functionality to well known classes?
PS: I tried to make another class which inherits from Int32, but cannot derive from sealed type 'int'.
You can add an extension method for int32.
public static class Int32Extensions
{
public static void HelloWorld(this int value)
{
// do something
}
}
Just remember to using the namespace the class is in.
I think you mention extension method programming guide of extension method
You're after Extension Methods.
There is nothing wrong with them OOP speaking because you don't have access to private variables nor alter the behaviour of the object in any way.
Its only syntactic sugar on what you've described exactly.
Q: Is that a good programming practice to add some other functionality to well known classes?
This type of discussion really belongs on 'Programmers'.
Please take a look at this discussion on Programmers, that has a lot of philosophical points on using extension methods:
https://softwareengineering.stackexchange.com/questions/77427/why-arent-extension-methods-being-used-more-extensively-in-net-bcl
Also:
https://softwareengineering.stackexchange.com/questions/41740/when-to-use-abstract-classes-instead-of-interfaces-and-extension-methods-in-c?lq=1
Use Extensions methods
static class Program
{
static void Main(string[] args)
{
2.HelloWorld();
}
public static void HelloWorld(this int value)
{
Console.WriteLine(value);
}
}
You may use extension method
like this:
public static class IntExtensions
{
public static string HelloWorld(this int i)
{
return "Hello world";
}
}
code:
class Base<T,U> where T:Base<T,U>,new() where U :class
{
protected static U _val = null;
internal static void ShowValue()
{
if(_val == null)new T(); //Without this line, it won't work as expected
Console.WriteLine (_val);
}
internal static void Virtual()
{
Console.WriteLine ("Base");
}
}
class Deriv :Base<Deriv,string>
{
static Deriv()
{
_val = "some string value";
}
internal static new void Virtual ()
{
Console.WriteLine ("Deriv");
}
}
public static void Main (string[] args)
{
Deriv.ShowValue();
Deriv.Virtual();
}
Thanks to the generics of .NET, I can create a bunch of specific classes reusing generic static methods defined in the generic base class. It can mimic inheritance polymorphism to some extent. But in order to initialize different version of static fields, I've to use static constructors. Unfortunately, we can't call them directly, therefore, we have to figure out a way to trigger it's invocation. The example given above showed a way. But I don't like either the instantiation,or the reflection approach. We also can't make a constraint on a static method of a generic parameter. So, I'd like to ask, if there is another way to do this kind of job!
Thanks beforehand!
~~~~~~~~~~~~~~~~
Some Conclusion (Maybe a little early):
It seems there is no workaround to deal with this kind of situation. I have to instantiate a subclass or use reflection. Considering the .cctors need merely be called once, I'm in favor of the reflection approach, because in some case, a new() constraint is just not a choice - like you're not supposed to expose the parameterless ctor to user.
After conducting further experiment, I find out that the .cctors may be called multi-times but only the first invocation will affect the setting of static fields. That's weird, but a good weirdness!
class MyClass
{
static int _val = 0;
static MyClass()
{
_val++;
Console.WriteLine (_val);
}
}
public static void Main (string[] args)
{
ConstructorInfo ci = typeof(MyClass).TypeInitializer;
ci.Invoke(new object[0]);
ci.Invoke(new object[0]);
ci.Invoke(new object[0]);
}
//result:
//1
//1
//1
//1
I would strongly advise you to rethink your design. Attempting to use this sort of workaround for "static inheritance" is fighting against some of the core designs of .NET.
It's unclear what bigger problem you're trying to solve, but trying "clever" code like this to simulate inheritance will lead to code which is very hard to maintain and diagnose in the longer term.
Without actually using a member of Deriv (or creating an instance of it), you basically won't trigger the static constructor. It's important to understand that Deriv.ShowValue() is basically converted into a call to
Base<Deriv, string>.ShowValue();
... so you're not actually calling anything on Deriv. Your calling code would actually be clearer if it were written that way.
EDIT: One other (clearly unfortunate) reason to avoid using type initializers explicitly is that there's a bug in .NET 4.5 which causes an exception to be thrown inappropriately in some cases. See my question on the topic for more information.
The correct solution is to invoke the type initializer (= static constructor) like this:
typeof(T).TypeInitializer.Invoke(null, null);
It needs both nulls. Specifying only one gives a MemberAccessException.
Thus, your code might want to look something like this:
internal static void ShowValue()
{
if (_val == null)
{
if (typeof(T).TypeInitializer != null)
typeof(T).TypeInitializer.Invoke(null, null);
if (_val == null)
throw new InvalidOperationException(string.Format("The type initializer of {0} did not initialize the _val field.", typeof(T)));
}
Console.WriteLine(_val);
}
And with that, you can remove the new() constraint.
You have no control of when the static constuctor will execute, but what is guaranteed is that it will run before accessing any static property or method and before instantiation.
There is really no reason to want the static constructor to execute at an earlier point. If you are not using anything from the class but you want the code in the static constructor to run, then something is wrong in your design.
Static constructors are automatically, only once. You cannot call them yourself.
An example from here:
public class Bus
{
// Static constructor:
static Bus()
{
System.Console.WriteLine("The static constructor invoked.");
}
public static void Drive()
{
System.Console.WriteLine("The Drive method invoked.");
}
}
class TestBus
{
static void Main()
{
Bus.Drive();
}
}
output:
The static constructor invoked.
The Drive method invoked.
I direct you to the MSDN article on Static Constructors and about 10% down the page:
A static constructor is called automatically to initialize the class
before the first instance is created or any static members are
referenced.
An existing type in C# need to be extended with some new methods, so that the following meets:
extension methods should resist in another assembly
they should appear like static methods of the original type
they should also be visible to implementors of derived classes of the original type
Example, Assembly Orig.dll:
public class Orig {
public static void Method1() { }
}
Assembly Extend.dll:
// method, which extends Orig in a static context is needed ...
// ??
// public static void Method2() { }
Usage Example (ideal):
public class Usage : Orig {
Method1(); // naturally working
Method2(); // <- this is needed
}
public void SomeFunc() {
Orig.Method2(); // <- this should ideally work also
}
The first attempt naturally coming in mind is using extension methods of C# 3.0. But unlike what I want, these (I think) only work on instances of the type being extended. In the context of a derived class this could be archieved like so:
public class Usage : Orig {
Method1(); // naturally working
this.Method2(); // working with C# 3.0 extension methods, but clumsy syntax
}
The first requirement (static context from outside the assembly) seems not to be fullfillable at all? So is there another potential approach?
#Edit: I may have not described the problem clearly. The needs are commented out in the following snippet (because they do not work with the common C# extension methods). So I try to find another approach, enabling the out-commented syntax:
// having a class
public class Orig { }
// which is extended with some functions (from another assembly)
public static class ExtOrig {
public static void ExtMeth (this Orig orig, string bla) {}
}
// derived classes should DIRECTLY!! see the extension
public class Derived : Orig {
public void MyMethod() {
// ExtMeth("inside orig"); <- does not work
this.ExtMeth("this derived"); // <- this keyword needed
}
// for static methods even worse:
public static void MyMethod2() {
// ExtMeth("inside orig"); <- does not work
// this.ExtMeth("this derived"); // <- 'this' not usable here :(
}
}
// for shorter syntax, static access would be needed
public class SomeClass {
private void SomeFunc() {
// Orig.ExtMeth("static orig"); <- does not work
new Orig().ExtMeth("outside orig"); // <- instance needed :(
// Derived.ExtMeth("static derived"); <- does not work
new Derived().ExtMeth("outside derived");
}
}
Extension methods can exist in a seperate assembly from the assembly containing the type you want to extend. The extending assembly simply needs to reference the original assembly. Any clients in other assemblies simply have to reference both the original assembly and the extending assembly.
Extension methods cannot appear as static methods on the type being extended. They can only appear as instance methods. There has been some discussion in the community about the need for static extension methods and possible implementations but, as far as I know, MS have not committed to adding this feature to C# as of yet.
Extension methods (with appropriate visibility) will be visible to both derived types, and any consumer of those derived types.
Extension methods or partial classes wont help you. Try using the Singleton design pattern as this may give you the behaviour you require using instance rather than static members