While searching for ways to get an instance of a singleton class i found many different approaches (some simple, some convoluted) but when messing around i found a way to do it which i didn't find anywhere else.
So what i basically do is:
public class Foo
{
public static Foo Invoker;
public Foo()
{
Invoker = this;
}
public void Method1()
{
//.....
}
}
And then from another class
public class Foo2
{
public Foo2()
{
//.....
}
public void Main()
{
var foo = Foo.Invoker;
//or
Foo.Invoker.Method1();
}
}
My app is single threaded so i don't care about thread safety (should i?) , so are there any other problems that this approach could cause that i am missing?
First of all, your 'singleton' pattern is quite easy to break. Let's say I'd create two instances of Foo in your application (changing the name of the class Foo1 to Bar for clarity):
var firstFoo = new Foo();
var bar = new Bar();
// Will access firstFoo when it calls Foo.Invoker
bar.Main();
var secondFoo = new Foo();
// Will access secondFoo when it calls Foo.Invoker. Huh?
bar.Main();
Another problem: Let's say I use Bar, without having initialized any Foo instances:
var bar = new Bar();
// Will throw a NullReferenceException, because Foo.Invoker is not yet initialized.
bar.Main();
As a rough rule of thumb, you should not set static fields from instances, because it leads to these kinds of situations.
Secondly, Bar probably does not need to know that Foo is a singleton in the first place. You could simply inject Foo in Bar's constructor.
public class Bar
{
private Foo foo;
public Bar(Foo foo) => this.foo = foo ?? throw new ArgumentNullException(nameof(foo));
public void Main()
{
// Now we know it is not null and, for Bar, it does not matter whether it's a singleton or not.
foo.Method1();
}
}
This way you could manage Foo instances easier in your application:
var firstFoo = new Foo();
var bar = new Bar(firstFoo);
// Does not make a difference now.
var secondFoo = new Foo();
This way, you could also leverage dependency injection containers like NInject or Microsoft.Extensions.DependencyInjection to manage your singletons for you.
If you really do want to create a single threaded singleton pattern, I would read Jon Skeet's blog post about singletons (good read!).
The simplest way of creating a singleton would be this approach. This way you create a single instance of Foo on the static property, that can never be changed. But read the blog post for more advanced patterns:
public class Foo
{
public static Foo Invoker { get; } = new Foo();
// Private constructor makes sure the only instance of Foo is created here.
private Foo()
{
}
}
Edit
If you'd want to make sure that all references to Foo in your application point to the last created instance of Foo, you could try something like this:
interface IFoo
{
void Method1();
}
class Foo : IFoo
{
private static int index = 1;
private int id;
private static NestedFoo invoker = new NestedFoo();
public static IFoo Invoker
{
get
{
if (invoker.Instance == null)
{
Create();
}
return invoker;
}
}
private Foo(int id) => this.id = id;
public static IFoo Create()
{
var foo = new Foo(index++);
invoker.Instance = foo;
return invoker;
}
public void Method1()
{
Console.WriteLine(this.id);
}
private class NestedFoo : IFoo
{
public Foo Instance { get; set; }
public void Method1() => Instance.Method1();
}
}
Now you'll always have a reference to the same instance of foo:
var foo = Foo.Create();
foo.Method1(); // 1
var foo2 = Foo.Create();
foo.Method1(); // 2
foo2.Method1(); // 2
Related
In Java I can instantiate an on-the-spot implementation of an interface:
interface Rubbable {
public void rub();
}
...
Rubbable r = new Rubbable() {
#Override
public void rub() {
// implementation
}
};
Like, a one-time implementation kind of thing.
I've tried to do the same thing with an abstract class in C#
public abstract class Foo
{
public abstract Bar Method();
}
Foo f = new Foo
{
public override Bar Method()
{
return new Bar();
}
}
But I'm getting the error
Cannot create an instance of the abstract type or interface 'Foo'
Can I instantiate an abstract class on-the-spot as I would like to? Some kind of, one-time-implementation without having to dedicate a whole class declaration in another part of the codebase to it.
Such a feature is not available in c#. A workaround could be to use delegates:
public class DelegateFoo : Foo {
private Func<Bar> barMethod();
public DelegateFoo(Func<Bar> tmp) => barMethod = tmp;
public override Bar Method() => barMethod();
}
var f = new DelegateFoo(() => new Bar());
But in such a simple case I the class does not add anything, so you might as well use a delegate directly.
This should sound like a really basic question, but I haven't been able to find an answer (even tho I know for sure there are plenty), I guess my Googling skills are bad, or maybe I don't know what to search for.
I have this code:
using System;
public class Program
{
public static void Main()
{
var service = new Service();
service.Execute();
}
}
public class Service
{
private int _foo;
public void Execute()
{
_foo = 1;
var bar = new Bar(_foo);
_foo = 2;
bar.WriteLine();
}
}
public class Bar
{
private readonly int _foo;
public Bar(int foo)
{
_foo = foo;
}
public void WriteLine()
{
Console.WriteLine(_foo);
}
}
How can I make it so it prints 2? (basically the new value after Bar has been initialized)
I tried using ref but no luck.
What you are trying to do doesn't make sense for a value type
Value types and reference types are the two main categories of C#
types. A variable of a value type contains an instance of the type.
This differs from a variable of a reference type, which contains a
reference to an instance of the type. By default, on assignment,
passing an argument to a method, or returning a method result,
variable values are copied. In the case of value-type variables, the
corresponding type instances are copied.
Normally you would create this as a property and set it accordingly
Given
public class Bar
{
public Bar(int foo) => Foo = foo;
public int Foo {get;set;}
public void WriteLine() => Console.WriteLine(Foo);
...
Usage
public void Execute()
{
var bar = new Bar(1);
// set the property instead
bar.Foo = 2;
bar.WriteLine();
...
Providing that I have a class as follows
public class Foo
{
public Foo(string someTitle, IFooService fooService)
{
// do stuff
}
}
I know that I can instantiate it like this using DI and autofac
public class Bar
{
public Bar(Func < string, IFooService, Foo > foo, IFooService fooService)
{
var foo = foo("some string", fooService);
}
}
but I'm wondering if there's any way for Bar to not have to know anything about IFooService? I'd like to not have to inject IFooService into Bar just to satisfy the func.
Essentially something like this
// pseudo code - don't use
public class Bar
{
public Bar(Func < string, Foo > foo)
{
var foo = foo("some string");
}
}
What I'm really trying to do in my app is remove all instances of Service Location, and rely solely on Dependency Injection.
Autofac should be able to do exactly what you want by using the Func<T> implicit relationship.
Here is a small repro showing how you can omit the IFooService parameter in the Func<T> and as long as the other dependencies can be resolved by Autofac, you're good to go.
Sample types that do some crazy work...
public class Bar
{
private Foo _foo;
// This constructor looks like what you're aiming for...
public Bar(Func<string, Foo> factory)
{
this._foo = factory("title");
}
public void ShowMeCoolStuff()
{
this._foo.DoWork();
}
}
public class Foo
{
private string _title;
private IFooService _service;
// The Foo class takes the title AND an IFooService...
public Foo(string title, IFooService service)
{
this._title = title;
this._service = service;
}
public void DoWork()
{
Console.WriteLine("Foo title = {0}", this._title);
this._service.DoMoreWork();
}
}
public interface IFooService
{
void DoMoreWork();
}
public class FooService : IFooService
{
public void DoMoreWork()
{
Console.WriteLine("FooService doing more work.");
}
}
When you register, make sure all the dependencies are registered - Foo, Bar, something implementing IFooService:
var builder = new ContainerBuilder();
builder.RegisterType<Foo>();
builder.RegisterType<Bar>();
builder.RegisterType<FooService>().As<IFooService>();
var container = builder.Build();
When you resolve, everything chains down the line. This resolution...
var bar = container.Resolve<Bar>();
bar.ShowMeCoolStuff();
...will yield the following console output:
Foo title = title
FooService doing more work.
There is fairly robust documentation with examples over on the Autofac site.
That's where you use factories for:
public interface IFooFactory
{
Foo CreateFoo(string value);
}
And bar can simply depend on IFooFactory.
The implementation can look as follows:
public class FooFactory : IFooFactory
{
private readonly IFooService fooService;
public FooFactory(IFooService fooService)
{
this.fooService = fooService;
}
public Foo CreateFoo(string value)
{
return new Foo(value, this.fooService);
}
}
But the given string seems like a runtime value, i.e. a value that changes from request to request or from call to call. Prevent mixing runtime values with design time dependencies as explained here, here and here. Instead, pass the runtime value as method argument to the Foo methods you are calling. That will completely remove the problem.
As far as I know you can can't pass parameters to a static constructor in C#.
However I do have 2 parameters I need to pass and assign them to static fields before I create an instance of a class. How do I go about it?
This may be a call for ... a Factory Method!
class Foo
{
private int bar;
private static Foo _foo;
private Foo() {}
static Foo Create(int initialBar)
{
_foo = new Foo();
_foo.bar = initialBar;
return _foo;
}
private int quux;
public void Fn1() {}
}
You may want to put a check that 'bar' is already initialized (or not) as appropriate.
You can't pass parameters to a static constructor, but you can pass parameters to the class itself - via generic type parameters.
Slightly crazy this idea, however, I'll just throw it out there anyway.
Make the class generic (with a TypeParam that will provide a parameter type) and place generic constraints on it (details in code example), then derive a new parameter type, which contains virtuals that you can use to read what they want the parameter values to be.
//base parameter type - provides the 'anchor' for our generic constraint later,
//as well as a nice, strong-typed access to our param values.
public class StaticParameterBase
{
public abstract string ParameterString{ get; }
public abstract MyComplexType ParameterComplex { get; }
}
//note the use of the new() generic constraint so we know we can confidently create
//an instance of the type.
public class MyType<TParameter> where TParameter:StaticParameterBase, new()
{
//local copies of parameter values. Could also simply cache an instance of
//TParameter and wrap around that.
private static string ParameterString { get; set; }
private static MyComplexType ParameterComplex { get; set; }
static MyType()
{
var myParams = new TParameter();
ParameterString = myParams.ParameterString;
ParameterComplex = myParams.ParameterComplex;
}
}
//e.g, a parameter type could be like this:
public class MyCustomParameterType : StaticParameterBase
{
public override string ParameterString { get { return "Hello crazy world!"; } }
public override MyComplexType { get {
//or wherever this object would actually be obtained from.
return new MyComplexType() { /*initializers etc */ };
}
}
}
//you can also now derive from MyType<>, specialising for your desired parameter type
//so you can hide the generic bit in the future (there will be limits to this one's
//usefulness - especially if new constructors are added to MyType<>, as they will
//have to be mirrored on this type as well).
public class MyType2 : MyType<MyCustomParameterType> { }
//then you'd use the type like this:
public static void main()
{
var instance = new MyType<MyCustomParameterType>();
//or this:
var instance2 = new MyType2();
}
I did consider a solution that employs custom type attributes applies to a type parameter, however this is easily a better way. However, you'll now be using your class always with a generic parameter type (unless you can use the deriving+specialisation trick) - possibly too clumsy for your liking.
I'd also prefer this over the other solutions presented here as it doesn't require creating any workarounds for the static initialisation - you can still use .Net's guarantee of single-time initialisation.
A word of warning - should you be reviewing your structure?
All that said - remember, though, since you can only parameterise the static once (or in this case, each uniquely parameterised static generic) - I would be asking myself why not just pull the code that is getting the parameters to give to the static, and place it in the static constructor in the first place? That way you don't actually have to resort to strange patterns like this!
I assume you mean static members of a class? In that case, you can do this:
public class MyClass
{
public static int MyInt = 12;
public static MyOtherClass MyOther = new MyOtherClass();
}
Those static members are guaranteed to be instantiated before any class is instantiated.
If you need complex logic, do it in a static constructor:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
static MyClass()
{
MyInt = 12;
MyOther = new MyOtherClass();
}
}
Edit
Based on your edit, I'd say just assign the values to what they need to be before you instantiate the class, like so:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
}
// elsewhere in code, before you instantiate MyClass:
MyClass.MyInt = 12;
MyClass.MyOther = new MyOtherClass();
MyClass myClass = new MyClass();
That said, this method gives you no guarantee that MyInt and MyOther are set before MyClass is instantiated. It will work, but requires discipline before instantiating MyClass.
One alternative pattern you might follow looks like this:
public class MyClass
{
private static int MyInt;
private static MyOtherClass MyOther;
private static bool IsStaticInitialized = false;
public static InitializeStatic(int myInt, MyOtherClass other)
{
MyInt = myInt;
MyOther = other;
IsStaticInitialized = true;
}
public MyClass()
{
if(!IsStaticInitialized)
{
throw new InvalidOperationException("Static Not Initialized");
}
// other constructor logic here.
}
}
// elsewhere in your code:
MyClass.InitializeStatic(12, new MyOtherClass());
MyClass myClass = new MyClass();
// alternatiavely:
MyClass myClass = new MyClass(); // runtime exception.
In Java I can write:
public class Foo {
public static Foo DEFAULT_FOO;
static {
DEFAULT_FOO = new Foo();
// initialize
DEFAULT_FOO.init();
}
public Foo() {
}
void init() {
// initialize
}
}
How can I get the same functionailty in C# (where static members are initialized before use)? And, if this is a bad thing to try to do, what is a better approach?
you use a static constructor, like this:
public class Foo
{
static Foo()
{
// inits
}
}
Here's more info.
Bottom line: it's a paramaterless constructor with the static keyword attached to it. Works just like the static block in Java.
Edit: One more thing to mention. If you just want to construct something statically, you can statically initialize a variable without the need for the static constructor. For example:
public class Foo
{
public static Bar StaticBar = new Bar();
}
Keep in mind that you'll need a static constructor if you want to call any methods on Bar during static initialization, so your example that calls Foo.Init() still needs a static constructor. I'm just sayin' you're not limited, is all. :)
Static is still the keyword in C#:
public class Foo {
public static Foo DefaultFoo;
static Foo {
DefaultFoo = new Foo();
// initialize
DefaultFoo.init();
}
public Foo() {
}
void init() {
// initialize
}
}