I have a database wrapper code like this (pseudo code):
class MyDBWrapper<objecttype> : Singleton
{
private DBDriver _Driver
Driver => Instance._Driver;
... tons of static functionality here referencing the driver
}
and then I can create custom databases from it:
class ObjectA_DB : MyDBWrapper<ObjectA_Type>
{
... all my calls using the static functionalities of the base class
}
this works very well...
Now, comes a different scenario:
I have a generic object: BaseObject
and a bunch of derived objects: ObjectA, ObjectB, etc
and they all require the same database code, so I did that:
class MyGenericDB<T> : MyDBWrapper<T> where T : BaseObject
{
.. common functionality
}
and then instantiated the type specific classes like this:
class MyTypeA_DB : MyGenericDB<ObjectA_Type>
class MyTypeB_DB : MyGenericDB<ObjectB_Type>
and this compiles properly, however the singleton code is causing problem when I try to access the instance
as it seems like it's recursing. Visual studio is unable to give a proper error as to what happens, but it hangs then crashes, so I am guessing a stack overflow.
The singleton code is here:
public abstract class Singleton<T> where T : class
{
private static readonly Lazy<T> _Instance = new Lazy<T>(CreateInstanceOfT, LazyThreadSafetyMode.PublicationOnly);
protected static T Instance => _Instance.Value;
private static T CreateInstanceOfT()
{
return Activator.CreateInstance(typeof(T), true) as T;
}
}
Did I miss anything obvious?
Not that used to this version of generics as my main work is in unity, and they update their core every decade, but I am pretty sure that you need your instance to be public to be allowed to read it.
When I write this, I traditionally create a private static instance of the passed type, and follow that up with a public static access function that creates that type if it does not yet exist.
A good full example for my own main engine can be found here:
http://wiki.unity3d.com/index.php/Singleton.
Related
I have
class X<T> : Base
{
//For exemple:
static T something();
}
And I can have
class A : X <A>
{
}
To logically have something like this:
class A : Base
{
static A something();
}
This works and works well.
But in my comprehension, it's kind of self-reference (A is the children of X, while X doesn't exists before A...), which is breaks the foundation of computer science, so I want to know what's wrong with my comprehension??
It's totally fine. You can do similar without generics too:
class Test
{
public static Test GetInstance()
{
return new Test();
}
}
I don't see any self-reference here. And actually it's quite useful pattern e.g. when implementing singletons. Simplified concept (I know, it should use locks, etc...):
public static class Singleton<T> where T : new()
{
private static T _instance;
public static T GetInstance()
{
return _instance ?? (_instance = new T());
}
}
Edit - Answering your comment question:
X<T> already exists for all suitable T parameters. By suitable I mean every type that suits generic constraint (or just every type when there is no constraint). And by every I mean not only all classes available within your assembly. Just every suitable type.
Generic class/method is just a template which is resolved for given particular generic type in runtime. That's why you don't have to even use the generic class at all in assemble it's declared within. And that's why your code works fine.
I currently have a class which I instantiate when I start my program. The class itself will create a new thread and begin to search for broadcasts from routers.
I have other windows, other then MainWindow, which needs to be able to access the data stored within the instance of this class. However, I'm not sure as to how the other windows can reference this data.
Is there some other way I can store the instance of this class so that it is accessible application wide? I need it to start right when the rest of the application starts, so it seemed logical (to me) to have the class be instantiated in the first window.
namespace Lalu_WPF
{
public partial class MainWindow : Window
{
// data storage for program
public FindRouter finder = new FindRouter();
public MainWindow()
{
......
Don't make Singleton (notice the capital letter). It is error prone in multiple threads environments(muttable Singletons) and bad for testing.
What are your requirements?
Do you have to have one object in one application or one object in whole CLR?
I bet the first one.
Make an object in your App class (App.xaml.cs) and then acces it via getter
App MyApplication = ((App)Application.Current);
MyApplication.Router;
Don't use a Singleton, it makes unit testing hard and your code surprising.
Give classes which need access to an instance the instance. That means that every class which needs this single instance should accept either by a constructor argument or setter. Whoever creates the class is then in charge of supplying the dependency. This is called Dependency Injection.
You could make the class a singleton and this way you could access this same instance across the entire application. You can see an example on the msdn website here
Do you have a Program class? In the Windows Forms projects that I do, variables such as that go in Program public static readonly members or in public static properties with get only.
What you're talking about sounds like the Singleton design pattern. You could create a singleton object, a static class, or (what I like) a Monostate object (an object that encapsulates the static class or single instance) , something like this:
public class SingletonWidget
{
private static readonly Implementation SingleInstance ;
public void DoSomething( int someValue )
{
SingleInstance.DoSomething( someValue ) ;
return ;
}
public int SomeProperty
{
get
{
return SingleInstance.SomeProperty ;
}
set
{
SingleInstance.SomeProperty = value ;
}
}
static SingletonWidget()
{
SingleInstance = new Implementation() ;
return ;
}
private class Implementation
{
public void DoSomething( int someValue )
{
// ...
}
public int SomeProperty { get ; private set ; }
}
}
Usage looks like normal object instantation:
SingletonWidget foo = new SingletonWidget() ;
foo.DoSomething(3) ;
but under the covers, there's just a single instance hanging around. Changing from a static class or singleton is trivial as only the wrapper needs to change. Building stubs or mocks is pretty easy, too.
It makes it easy to
Try a DI framework or some less complex implementation of a service locator. That will allow you to provide the instance where it is needed throughout your app without hardcoding in a singleton, which is then painful to write tests around.
I know that Ninject at least provides support for single instances application-wide. I haven't used it in a WPF application but I can't see why not.
As a basic example of a service locator you could do something like the following. I've called the shared class Foo:
public interface IFoo { ... }
public class Foo { ... }
public class ServiceLocator
{
IFoo _foo = new Foo();
public IFoo GetFoo() { return _foo; }
}
public class DependsOnFoo
{
public IFoo Foo = ServiceLocator.GetFoo();
...
}
DependsOnFoo.Foo is the shared instance of Foo by default but when writing automated tests you could swap it out with a stub or mock:
var testTarget = new DependsOnFoo();
testTarget.Foo = mockFooImplementation;
// now testTarget isn't bound to the Foo implementation
As far as I understand your question is how to store a reference to your finder rather than how to create it. If this is the case I would suggest using IDictionary Application.Current.Properties property, which is nothing but a collection of application-scope properties. At startup you can create your object and store a reference to it like this:
Application.Current.Properties["finder"] = new FindRouter();
Then, in any place of your program you can access it like
FindRouter finder = (FindRouter)Application.Current.Properties["finder"];
Hope this helps.
Although a static class has only one instance and can't be instantiated, a class with a private constructor can't be instantiated (as the constructor can't be seen), so every time you call this class, this is the same one instance?
Factory classes always follow the last convention (instance class with private constructor). Why is this?
Thanks
There's nothing stopping the class with the private constructor from having a public static method which returns instances of the class:
public class NoPublicConstructor
{
private NoPublicConstructor()
{
}
public static NoPublicConstructor NewInstance()
{
return new NoPublicConstructor();
}
}
As you can see, the static method does not return the same one instance.
edit: One of the reasons factory classes do this is to be able to separate responsibility in future versions: while your code always calls the factory creation method, the author may move all the "guts" out of that class into a different one and your code won't need to know the difference. Calling that class' (public) constructor ties it to an extent to the original class implementation.
You can't* get an instance from outside the class, but you can from inside. A static method or an inner class can create and return an instance of the class with a private constructor. The static class cannot be instanced by anything.
class Foo
{
private Foo()
{
}
public class Bar
{
public Bar()
{
}
public Foo GetFoo()
{
return new Foo();
}
}
}
..
Foo.Bar fooBar = new Foo.Bar();
Foo foo = fooBar.GetFoo();
Edit: *I use the term "can't" loosely. Brian Rasmussen pointed out in the comments to the OP that another method to obtain an instance is through a call through System.Runtime.Serialization.FormatterServices, and this is external to the class itself.
Foo foo = (Foo)System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject(typeof(Foo));
Creating a class with private constructor is the common pattern for implementing a "Singleton" object.
The Singleton usually will instantiate an instance of itself, and only allow access to it through a static "Instance" property, which means there's only ever one instance of the class.
The advantage of using a Singleton over a purely static class is that you can utilize interfaces and different implementation classes within the singleton. Your "Singleton" might expose an interface for a set of methods, and you can choose which exact implementation class to instantiate under the covers. If you were using a purely static class, it would be hard to swap out a completely different implementation, without impacting other code.
The main downside of Singleton is that it's difficult to swap out the implementation class for testing, because it's controlled within the Singleton private methods, but there are ways to get around that.
I' ve been doing some programming lately and faced an issue which i found weird in c#. (at least for me)
public class Foo
{
//whatever
public class FooSpecificCollection : IList<Bar>
{
//implementation details
}
public FooSpecificCollection GetFoosStuff()
{
//return the collection
}
}
I want the consumer of Foo to be able to obtain a reference to FooSpecificCollection, even perform some operations on it. Maybe even set it to some other property of Foo or smth like that, but not To be able to CREATE an instance of this class. (the only class that should be able to instatiate this collection should be Foo.
Is my request really that far-fetched? I know that people way smarter defined c# but shouldn't there be such an option that a parent class can create a nested class instance but nobody else can't.
So far I created a solution to make an abstract class, or interface available through the property and implement a concrete private class that is not available anywhere else.
Is this a correct way to handle such a situation.?
The way embedded classes work is that they, as members of the outer class, get access to private members of that outer class. But not the other way around (what is what you want).
You can shield the constructor of FooSpecificCollection, but then the Factory has to be part of FooSpecificCollection itself. It could enlist the outer class:
public class Foo
{
public class FooSpecificCollection : List<Bar>
{
private FooSpecificCollection () { }
public static FooSpecificCollection GetFoosStuff()
{
var collection = new FooSpecificCollection ();
PrepareFooSpecificCollection(collection);
return collection;
}
}
private static void PrepareFooSpecificCollection(FooSpecificCollection collection)
{
//prepare the collection
}
}
Make your nested class private and make the return value of GetFoosStuff IList<Bar> instead of FooSpecificCollection.
Also, there's a good chance that deriving from List<Bar> is a bug.
If you are creating a library for others to use, you could make the constructor internal. Anyone outside the library will not be able to access it. If you are concerned about calling the constructor in your own project, just don't call it outside the parent class.
We create classes all the time which are not directly related to other classes, but the constructors don't have to be hidden from non-related classes. We (the programmers) know the the objects are not related so we don't ever create an instance of one in the other.
There is a solution but I don't think I would use it in my App :)
The idea is to have derived class from FooSpecific which is private and can be used only inside Foo but has public constructor, so Foo can create its instances.
public class Foo
{
//whatever
public class FooSpecific
{
// Protected contructor.
protected FooSpecific()
{
}
// All other code in here.
}
// Private helper class used for initialization.
private class FooSpecificInitHelper : FooSpecific
{
public FooSpecificInitHelper()
{
}
}
// Method in foo to create instaces of FooSpecific.
private FooSpecific CreateFooSpecific()
{
return new FooSpecificInitHelper();
}
}
No, and it doesn't really make sense.
I mean the whole point is so that you could potentially return other instances; but who will be deriving from that class anyway? Certainly not any other classes (Because that would be wrong, and imply it shouldn't be hidden inside the main class), so ...
I am currently designing a class library that will provide data to a web application graph rendering engine in C#. I am currently defining the interfaces of this library.
I have a IGraphData interface which I would like to cache using a service that accesses the cache, this is called IGraphDataCacheService and has set and get methods to add and retrieve IGraphData objects to and from the cache. the cache service will be a singleton.
I am confused about the correct way to implement this, so that there is only one cache service that can get and set generic IgraphData objects.
I came up with this:
interface IGraphDataCacheService {
IGraphData<object> Get(string identifier);
void Set(IGraphData<object> graphData);}
or this:
T Get<T, P>(string identifier) where T : IGraphData<P>;
void Set<T,P>(T graphData) where T : IGraphData<P>;
Can any one offer any advice help?
Thanks
Why don't you just make the interface generic instead?
interface ICacheService<T> {
T Get(string identifier);
void Set(T graphData);
}
if you wanted, you could type-constrain T to be of type IGraphData, or you could write it as:
interface IGraphDataCacheService<T> {
IGraphData<T> Get(string identifier);
void Set(IGraphData<T> graphData);
}
A few points:
I'd probably rename the interface methods to be more emblematic of a caching service. For example, Fetch and Store instead of Get and Set, which makes it sound like you're getting or setting the provider rather than the data to be cached.
Ensuring that there is only one cache is an implementation detail, not an interface one.
To implement a singleton, try something like:
public class SingletonCacheService : IGraphDataCacheService {
private static Singleton instance;
private Singleton() {}
// snip implementation of IGraphDataCacheService methods ...
public static Singleton Instance {
get {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
}
Note that this simple version isn't threadsafe.
Both alternatives seem plausible at a glance; my hunch is that you need to write some 'typical' client code to decide. e.g. Does the typical client 'know' the type of data associated with the identifier it's looking up? Good API design requires identifying the main use scenarios and using that to inform the design.
If I understand your question correctly you are wanting to treat the generic types like they are the same, but in current .NET implementation you can't do this.
IGraphData<string> can't be passed as a IGraphData<object> they are actually different types even though string is an object, the generic types are not related and can't be cast or passed like they are the same.
If you control the IGraphData interface you can create a IGraphData interface and derive IGraphData from it and use IGraphData to access the cache. It just depends on how you are using it and what you have the control over.
You can do what you want in C# 4.0. There is an article about it here
You can't ensure there's only a single instance implementing an interface. However, you can make a class (e.g. GraphDataCacheServiceImpl) implementing the interface a singleton by sealing it and providing only a getter property, with the object created as a static variable from a private constructor. See the below. As far as generics, it's not exactly clear what you're seeking to accomplish. But I would guess the below is close to what you want.
interface IGraphDataCacheService<T> {
IGraphData<T> Get(string identifier);
void Set(IGraphData<T> graphData);
}
public sealed class GraphDataCacheServiceImpl<T> : IGraphDataCacheService<T>
{
private GraphDataCacheServiceImpl()
{
// ..
}
static GraphDataCacheServiceImpl()
{
Instance = new GraphDataCacheServiceImpl<T>();
}
public IGraphData<T> Get(string id)
{
return new GraphDataImpl<T>();
}
public void Set(IGraphData<T> graphData)
{
}
public static GraphDataCacheServiceImpl<T> Instance {get; private set;}
}