I'm sure this must have been asked already, but I can't seem to find the answer. I need to know how to access a static method, when the class it is defined within has been hidden by an instance method with the same name.
I have a class which exposes a static method as follows:
public class Plan
{
public static Plan Generate(Project project)
{
var plan = new Plan();
// ...
return plan;
}
}
I then have another class which contains a method called "Plan", from which I want to call the static method mentioned above:
public ActionResult Plan(int id)
{
// ...
var plan = Plan.Generate(project);
// ...
}
The problem is that the class name 'Plan' is hidden by the method name, so I cannot call the static method directly.
Qualify your access to the Plan type with the type's name. For example:
YourNamespace.Plan.Generate
That said, static methods are bad mkay. Make yourself an IPlanFactory, bind PlanFactory to it and let dependency injection do the rest (assuming you're using constructor injection and not that hairbrained dependency resolver stuff). Now it's unambigiously _planFactory.Generate(...) and you've just increased testability. Give yourself a raise!
Related
Is there an option to automatically pass this as parameter to a function? For example, you can use [CallerMemberName] to automatically pass string name. I'm looking for exact option with this.
Example:
void PassMeThis([AutomaticThisParam] object source);
and usage:
public class SomeClass{
void SomeMethod(){
PassMeThis(); // instead of PassMeThis(this)
}
}
Yes absolutely. This is called an extension Method.
Create a static class
Public static class MethodExtensions
Add a static method to it like this
public static PassMeThis(this SomeClass model) { // }
Call the method like this (referring to your code example):
this.PassMeThis()
And it's automaticly filled.
I hope thats what you were looking for
If PassMeThis is in the same class (or ancestor), as in your example, there is no point, this is avaiable there, too.
If it is in another class, there is no way to automatically get a reference to the calling object: IS there any way to get a reference to the calling object in c#?
I have a (growing) list of Data-Generators. The generator that I need is created by a factory class. The generators all implement a common Interface, which includes among other things a static string name.
What I would like to do: Call the factory.Create method with a string parameter for the above mentioned name. The create method finds the generator with this name and returns a new instance of said generator.
Bonus in my opinion of this way to do it: I only have to add new generator classes without having to edit the factory.
Question:
Is this a good way to handle this problem?
How can I find all generators? Reflection over every implementation of the interface/every member of the namespace (unique for the generators + their interface)?
Is it correct to call this way of working a factory, or is this some different pattern?
In the end I would call the factory like this (simplified):
//Caller
public DataModel GetData2()
{
var generator = new DataFactory().Create("Gen.2");
return generator.GetData();
}
//Factory
public class DataFactory
{
public AbstractDataGenerator Create(string type)
{
//Here the magic happens to find all implementations of IDataGenerator
var allGenerators = GetImplementations();
var generator = allGenerators.FirstOrDefault(f => f.name == type);
if (generator != null)
return (AbstractDataGenerator)Activator.CreateInstance(generator);
else
return null;
}
}
//Interface
public abstract class AbstractDataGenerator
{
public static string name;
public abstract DataModel GetData();
}
//Data-Generators
public class DataGen1 : AbstractDataGenerator
{
public static string name = "Gen.1";
public DataModel GetData()
{
return new DataModel("1");
}
}
public class DataGen2 : AbstractDataGenerator
{
public static string name = "Gen.2";
public DataModel GetData()
{
return new DataModel("2");
}
}
Should the magic GetImplementations() in the factory be done via Reflection or somehow different? Should I use a completely different approach?
Since answers refer to IoC and DI: This project uses NInject already, so it would be available.
Switched from interface to abstract class.
Is this a good way to handle this problem?
Having a factory to get an instance of the logic class you need by some key - I believe it is a good way. It is a pattern that I use a lot myself. About the way you have your key - I'd prefer to not have it as a static member (regardless to the fact that interfaces can't have static members) but just as a property and to add a base class to the IDataGenerator. That base class will have a constructor that will get the name - That way each new DataGenerator you create will have to set it and you wont forget.
About having the name as a string - I personally prefer having it "strongly typed". What I mean is that if I pass Gen . 2 instead of Gen.2 with strings I will discover this problem only in runtime. Possible other ways (if you want, because a simple string is fine too - a matter of taste):
Replace strings with an enum
Have a static class with static readonly strings for all your values - then in your code use those values. You get the benifits of the intellisense and of not getting the string wrong but better than enum - you can just still pass strings that are not in the "list" so you can add new ones as add-ons.
Have a RequestGenerator object, with each Generator being IDataGenerator<TGeneratorRequest>. This might be an overkill but if you have also extra information you need for the creating of a DataGenerator which differs between them then consider it .
How can I find all generators? Reflection over every implementation of the interface/every member of the namespace (unique for the generators + their interface)?
Yes, reflection can be a good way to do so. However, I would suggest to read into Dependency Injection and IoC Containers like Castle Windsor for example. There are things out there that already implement it for you, so why to re-invent the wheel :)
DI is a life changer concept in my opinion
Is it correct to call this way of working a factory, or is this some different pattern?
Yap. It is a Factory
Should the magic GetImplementations() in the factory be done via Reflection or somehow different?
See answer for question 2
This is where constructor injection can REALLY shine. Look into dependency injection tools and employ one! It also checks your "Bonus" request.
Here's what your factory might look like with constructor injection:
public class DataFactory
{
private Dictionary<string, IDataGenerator> generators;
public DataFactory(IDataGenerator[] generatorReferences)
{
this.generators = generatorReferences
.ToDictionary(k => k.name, v => v);
}
public IDataGenerator Create(string type)
{
IDataGenerator generator = null;
this.generators.TryGetValue(type, out generator);
return generator;
}
}
Most DI software has the capability to automatically scan assemblies for implementations of a certain type (e.g. IDataGenerator) and register those with itself, when it constructs an instance of your DataFactory it'll automatically include them.
I am not overly familiar with implementing lambdas and expressions, but I've used to this syntax many times in MVC where the lambda is identifying a property on an object:
Html.Label(model => model.Foo)
In my app I am using Ninject conditional bindings to supply the instance of the Settings class which is injected when I request an instance of Class. My Class looks like this:
public class Class
{
private readonly Settings settings;
public Settings Settings { get { return settings; } }
public Class(Settings settings)
{
this.settings = settings;
}
}
I have some code which looks like this to get an instance of Class. I am aware this is the service locator anti pattern, but we have no choice in this case due to other constraints:
var settings = new Settings();
var instance = Ioc.Instance.Get<Class>("settings", settings);
I would like to refactor it to look like this so that it is strongly typed, using a lambda to specify which argument on the constructor I am supplying:
var settings = new Settings();
var instance = Ioc.Instance.Get<Class>(x => x.settings, settings);
So, is this possible, and what would the code look like?
Conceptually there is a lack of the factory (factory interface), so it should be introduced to avoid using the container directly.
The Ninject Factory (factory interface) extension could be used to create the instance, as follows:
Declare a factory interface:
public interface IFactory
{
Class Create(Settings settings);
}
Add a binding to the composition root:
kernel.Bind<IFactory>().ToFactory();
Use the factory to get an instance:
var settings = new Settings();
var factory = Ioc.Instance.Get<IFactory>();
var instance = factory.Create(settings);
Please see the ninject/ninject.extensions.factory for the alternatives.
The problem with constructor argument names and expressions is, that an expression is only valid / complete when it covers all parameters of the constructor. Now i suppose you want to inject a few of the parameters (have ninject handle them) and for one or two specific parameters you want to pass a value, let's say it looks like:
public interface IFoo { }
public class Foo : IFoo
{
public Foo(IServiceOne one, IServiceTwo two, string parameter) {...}
}
Ninject supports ctor expressions, but only for bindings, and they work like this:
IBindingRoot.Bind<IFoo>().ToConstructor(x =>
new Foo(x.Inject<IServiceOne>(), x.Inject<IServiceTwo>(), "staticArgument");
so instead of only specifying the "staticArgument" which you are interested in, you also have to specify IServiceOne and IServiceTwo. What if the constructor changes? Well the call needs to be adapted as well! Lot of work for just passing a single simple parameter.
Now if you still want to do this i'd suggest having a look at the ToConstructor code and creating a similar extension for a Get call which will translate some call
IResolutionRoot.Get<IFoo>(x =>
new Foo(
x.Ignore<IServiceOne>(),
x.Ignore<IServiceTwo>(),
x.UseValue("mystring"));
to
IResolutionRoot.Get<IFoo>(new ConstructorArgument("parameter", "mystring"));
However, i would suggest going with #Sergey Brunov 's answer and use Ninject.Extensions.Factory. Now I think your going to say that it's no good because you'll still have to specify the parameter name,.. which is not refactor safe and a hassle (no code completion...).
However, there's a solution to the problem: Instead of using a constructor argument which "matches" the name of the argument, you can use a type matching argument.
Ok, there's a catch. If you've got multiple arguments of the same type,.. well it won't work. But i think that's seldomly the case and you can still introduce a container data-class to address it:
public class FooArguments
{
string Argument1 { get; set; }
string Argument2 { get; set; }
}
Now how can you use type matching?
There's two ways:
Use a Func<string, IFoo> factory. Just inject Func<string, IFoo> into where you want to create and IFoo.
Extend the Factory extension. Yes you've heard right ;-) It's actually not that difficult. You "just" need to implement a custom IInstanceProvider (also see http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction/) so you can something like:
public interface IFooFactory
{
IFoo Create([MatchByType]string someParam, string matchByName);
}
(==> use an attribute to tell the factory extension how to pass the parameter to the Get<IFoo>request).
Look at following article -
http://handcraftsman.wordpress.com/2008/11/11/how-to-get-c-property-names-without-magic-strings/
Specifically
public static class Extensions
{
public static string GetPropertyName<T,TReturn>(this Expression<Func<T,TReturn>> expression)
{
MemberExpression body = (MemberExpression)expression.Body;
return body.Member.Name;
}
}
Note - This method may not work for all possible ways in which one can use expressions to indicate a property name for a class, and hence may need to be enhanced based on your needs (how generic you need it to be).
But essentially, once you have this helper method, your call becomes
var settings = new Settings();
Ioc.Instance.Get<Class>(GetPropertyName(x => x.settings), settings);
Can i access a method from a instance of the class? Example:
class myClass
{
private static int n = 0;
public static myClass()
{ n = 5;}
public static void Afis()
{
Console.WriteLine(n);
}
}
and in the void Main:
static void Main()
{
myClass m = new myClass();
m.Afis();
}
This gives me: cannon be accessed with an instance referece. Is it because i declared the function static? If that is so when should I use static and when not because in c++ if i declare something with static it just initialize once. Is that the case with c#?
You need to use the class name rather than your variable name to access the static method.
myClass.Afis();
I've attached a link to the Static Classes and Static Class Members programming guide as you've asked when you should use them and not use them.
A little exert from the programming guide:
A static class can be used as a convenient container for sets of
methods that just operate on input parameters and do not have to get
or set any internal instance fields. For example, in the .NET
Framework Class Library, the static System.Math class contains methods
that perform mathematical operations, without any requirement to store
or retrieve data that is unique to a particular instance of the Math
class.
Static methods are called through the class itself, not an instance of the class.
static void Main()
{
myClass m = new myClass();
myClass.Afis();
}
That's right - it's a static function and therefore is called like:
myClass.Afis();
Is it because i declared the function static?
Exactly.
If that is so when should I use static
Guess what - from the error: when you do not need to access instance variables.
because in c++ if i declare something with static it just initialize once. Is that the case with
c#?
If you mean a static constructor - yes.
Basically what you have there is not a "class", but a static class that can not be instantiated at all.
Static method is method who connect to the class ad not to instance.
You use this if you want that every instance can use the same method.
For example if I want to count the instances of class I use static property.
To access static methods and properties you have to use the name of the class and not the name of instance.
Yes - as you suspect - you cannot access an static method via an instance of the object, only via the type itself.
In other words:
myClass.Afis();
Naturally - the converse is also true; you cannot access an instance method via the type either.
You can find out more about when to, and no to, use static in other questions such as this one, but I would say that static limits certain desirable things like testability and polymorphism (to name just a couple), and so shouldn't be your "default position".
You marked your method as static. Thus you have to access it via the type.
Static methods are used when the method refers to the type and does not use instance information. String.IsNullOrEmpty(string s) is such a static method. It belongs to the string class but does not need an instance environment. Whereas the ToString() method that every object inherits from object needs an instance context to define what to express as a string.
In my custom attribute's static constructor, I search the loaded assembly for all classes decorated with my attribute and perform some action on them.
I would like the static constructor to be called as soon as possible during runtime, preferably before execution of the static void Main() entry point.
Currently it only gets called after I make some call to the attribute. I could make such a call elsewhere in my program, but ideally the attribute's functionality would be self-contained.
Looking for answers, I read this on MSDN:
The user has no control on when the static constructor is executed in the program.
But surely there is some tricky, sly, or mischievous workaround to get a static constructor to be called ASAP. Perhaps an attribute, reflection, or some other kind of magic could be used. Can it be done?
Because people would undoubtedly tell me that there is no good reason to do what I ask, I present my purpose and my code: I am trying to use attributes to declaratively configure a db4o factory. If my attribute's static constructor is called after I've already established a connection, then it has no effect and is useless. Therefore it must be called before my program gets a chance to establish such a connection.
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
sealed public class CascadeOnUpdateAttribute : Attribute
{
public bool Flag { get; private set; }
public CascadeOnUpdateAttribute() : this(true) { }
public CascadeOnUpdateAttribute(bool flag)
{
Flag = flag;
}
static CascadeOnUpdateAttribute()
{
var targets = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
from attribute in type.GetCustomAttributes(typeof(CascadeOnUpdateAttribute), false).Cast<CascadeOnUpdateAttribute>()
select new { Type = type, Cascade = attribute.Flag };
foreach (var target in targets)
{
Db4oFactory.Configure().ObjectClass(target.Type).CascadeOnUpdate(target.Cascade);
}
}
}
Update:
I ended up using an abstract attribute with a static method. This way I can derive as many attributes as I like and they will all be applied to a specified config by calling this one method.
public abstract class Db4oAttribute : Attribute
{
public abstract void Configure(IConfiguration config, Type type);
public static void ApplyAttributes(IConfiguration config)
{
var targets = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
from attribute in type.GetCustomAttributes(typeof(Db4oAttribute), false).Cast<Db4oAttribute>()
select new { Type = type, Attribute = attribute };
foreach (var target in targets)
{
target.Attribute.Configure(config, target.Type);
}
}
}
And the call site:
Db4oAttribute.ApplyAttributes(Db4oFactory.Configure());
_db = Db4oFactory.OpenFile("Test.db4o");
As Marc says, I would do it explicitly in Main if I were you.
You can invoke the type initializer for a type explicitly using the Type.TypeInitializer property and invoking it. However, this will cause it to run again even if it's already been run which could produce unexpected results.
I would personally move that code out of the static initializer completely. It's configuration code - why not just make it a static method which you can call explicitly? I'm not even sure I'd have it in the attribute class itself, but at least explicitly calling:
CascadeOnUpdateAttribute.ConfigureDb4oFactories();
is clearer than calling a dummy method or forcing type initialization some other way, just to get a side effect.
If you want the static constructor to get called, then add a dummy method to the type and simply call it at the start of your code (Main etc); if it is a trivial / empty method you might want to mark it for no inlining etc.
class SomeType {
static SomeType() {
Console.WriteLine("SomeType.cctor");
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Init() { }
}
static class Program {
static void Main() {
SomeType.Init();
Console.WriteLine("hi");
}
}
You can use reflection to call the static constructor, but I don't recommend it; if you use reflection you can actually call the .cctor multiple times, and that is never a good thing...
You can avoid the static dummy method by calling
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(CascadeOnUpdateAttribute).TypeHandle)
I think the use of the static constructor smells; I would consider refactoring your code to control access to the db4o factory so that you don't need to use it.