konto usunięte

Temat: Klasa bazowa dla singletona w C#

Jak zrobić klasę bazową dla singletona w C#. Próbowałem tego:


public abstract class SingleTon<T> where T : SingleTon<T>, new()
{
protected T instance = null;
public T Instance
{
get
{
if (this.instance == null)
this.instance = new T();
return this.instance;
}
}

private SingleTon() { }
}


Ale to wymusza publiczny konstruktor bez parametrów dla klas dziedziczących. Jak obejść problem?

konto usunięte

Temat: Klasa bazowa dla singletona w C#

Tak troche pobocznie, ale nie jestem w stanie tego zrozumiec - po co ci klasa bazowa dla singletona?

konto usunięte

Temat: Klasa bazowa dla singletona w C#

wypowiedz skasowanaJarosław K. edytował(a) ten post dnia 19.09.08 o godzinie 10:07

konto usunięte

Temat: Klasa bazowa dla singletona w C#

Krzysztof K.:
Tak troche pobocznie, ale nie jestem w stanie tego zrozumiec - po co ci klasa bazowa dla singletona?

W nowym module będę miał trochę obiektów, które w większości są bardzo podobne, wszystkie muszą być singletonami, a docelowo zarządzanie instancjami będzie bardziej skomplikowane niż prosty singleton (będzie wersjonowanie w oparciu o wersję trzymanych danych o ile to nie jest masło maślane lol). Stąd ta idea.

konto usunięte

Temat: Klasa bazowa dla singletona w C#

Jarosław K.:
Sebastian Pienio:
Jak zrobić klasę bazową dla singletona w C#. Próbowałem tego:

Najlepiej go nie robić ;)

najs dżołk komplitli oftopik

konto usunięte

Temat: Klasa bazowa dla singletona w C#

wypowiedz skasowanaJarosław K. edytował(a) ten post dnia 19.09.08 o godzinie 10:06
Sebastian H.

Sebastian H. Starszy Programista,
VidCom.pl

Temat: Klasa bazowa dla singletona w C#

Propnowałbym zrobić prostą fabrykę dla obiektów. Zrobiłbym prosty atrybut dla klas np. SingletonAttribute a potem taką fabrykę:

public class SingletonFactory
{
private Hashtable instances = new Hashtable();

private static readonly SingletonFactory instance = new SingletonFactory();

private SingletonFactory()
{

}

public T GetObjectInstance<T>() where T : class
{
Type type = typeof(T);
if(type.GetCustomAttributes(typeof(SingletonAttribute), true).Length > 0)
{
Object o = instances[type];
if(o != null)
{
return o as T;
}
else
{
T instance = type.InvokeMember(type.Name,
BindingFlags.CreateInstance |
BindingFlags.Instance |
BindingFlags.NonPublic,
null, null, null) as T;
instances.Add(type, instance);
return instance;
}
}
else
{
return Activator.CreateInstance<T>();
}
}

public static SingletonFactory Instance
{
get
{
return instance;
}
}
}

Klasy które będa tworzone jako singletony mogą mieć prywatny konstruktor.Sebastian H. edytował(a) ten post dnia 01.09.08 o godzinie 11:24

konto usunięte

Temat: Klasa bazowa dla singletona w C#

Sebastian H.:
Propnowałbym zrobić prostą fabrykę dla obiektów. Zrobiłbym prosty atrybut dla klas np. SingletonAttribute a potem taką fabrykę:
return Activator.CreateInstance<T>();
Klasy które będa tworzone jako singletony mogą mieć prywatny konstruktor.

Dzięki, dokładnie o coś takiego mi chodziło, top man!
Kazimierz Kuta

Kazimierz Kuta Microsoft MVP

Temat: Klasa bazowa dla singletona w C#

Problemy z implementacją:

1) nie dasz rady nałozyć ograniczenia na klasę tak, aby nie implementowała ona publicznego konstruktora
2) thread safety (http://www.yoda.arachsys.com/csharp/singleton.html i http://msdn.microsoft.com/en-us/library/ms998558.aspx)

imho lepsze, bo adresujące problem 2 jest rozwiązanie opisane tutaj: http://www.cognitivecoding.com/2008/03/hidden-gem-sing... i komentarze tutaj: http://www.dotnetkicks.com/csharp/Hidden_Gem_Singleton....

konto usunięte

Temat: Klasa bazowa dla singletona w C#

Kazimierz Kuta:
Problemy z implementacją:

1) nie dasz rady nałozyć ograniczenia na klasę tak, aby nie implementowała ona publicznego konstruktora

Nie potrzebuję wymuszać na klasie tego, żeby nie miała publicznego konstruktora. Najważniejsze, żeby mieć nie musiała.
2) thread safety (http://www.yoda.arachsys.com/csharp/singleton.html i http://msdn.microsoft.com/en-us/library/ms998558.aspx)

imho lepsze, bo adresujące problem 2 jest rozwiązanie opisane tutaj: http://www.cognitivecoding.com/2008/03/hidden-gem-sing... i komentarze tutaj: http://www.dotnetkicks.com/csharp/Hidden_Gem_Singleton....

To już szczegóły, ale chyba każdy dobry developer zakłada, że jak nie napiszą "thread-safe" to może coś być nie tak. Poza tym przykład, który na tym blogu podają:

if (instance == null)
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
}
}


jest nieczysty. Wystarczy jeden lock przed sprawdzeniem instance==null.

Ale to dygresja i już prawie offtopic ;)
Kazimierz Kuta

Kazimierz Kuta Microsoft MVP

Temat: Klasa bazowa dla singletona w C#

kod jest, a nad nim na czerwono: Bad Code. Don't use it.

pod kodem w artykule na yoda.arachsys.com jest opisane, dlaczego jest bad ;) A generalnie chodzi o to, że lock jest czasochłonny i aby go ominąć w każdorazowym wywołaniu instancji można zrobić taki myk... można tak, można lepiej ;)

Co do konstruktorów: Nie da się w taki sposób skonstruować uniwersalnej fabryki singletonów. Da się natomiast skonstruować fabrykę, która będzie produkować tylko jedną instancję danej klasy (OneInstatnceFactory ;) ). Niestety jeśli klasa będzie umożliwiała skonstruowanie samej siebie (poprzez publiczny konstruktor lub wystawienie instancji) to już nie możesz być pewien, że nie masz dwóch lub więcej instancji klasy. Dopóki sam piszesz swój kod jest ok...

ps.: zainteresuj się tym rozwiązaniem http://www.codeplex.com/ObjectBuilder (http://www.google.pl/search?hl=pl&rls=com.microsoft%3A... ale nie wiem czy nie jest ono zbyt ciężkie

konto usunięte

Temat: Klasa bazowa dla singletona w C#

Kazimierz Kuta:
kod jest, a nad nim na czerwono: Bad Code. Don't use it.

pod kodem w artykule na yoda.arachsys.com jest opisane, dlaczego jest bad ;) A generalnie chodzi o to, że lock jest czasochłonny i aby go ominąć w każdorazowym wywołaniu instancji można zrobić taki myk... można tak, można lepiej ;)

Upsss, sorry, zadziałałem jak kompilator - zobaczyłem kod, przepuściłem, znalazłem warninga i dalej nie wszczubiałem nosa...
Co do konstruktorów: Nie da się w taki sposób skonstruować uniwersalnej fabryki singletonów. Da się natomiast skonstruować fabrykę, która będzie produkować tylko jedną instancję danej klasy (OneInstatnceFactory ;) ). Niestety jeśli klasa będzie umożliwiała skonstruowanie samej siebie (poprzez publiczny konstruktor lub wystawienie instancji) to już nie możesz być pewien, że nie masz dwóch lub więcej instancji klasy. Dopóki sam piszesz swój kod jest ok...

ps.: zainteresuj się tym rozwiązaniem http://www.codeplex.com/ObjectBuilder (http://www.google.pl/search?hl=pl&rls=com.microsoft%3A... ale nie wiem czy nie jest ono zbyt ciężkie

Dotychczas moje serce było bliższe:
http://www.castleproject.org/container/index.html

o Object Builderze szczerze mówiąc nie słyszałem, używałeś go?

konto usunięte

Temat: Klasa bazowa dla singletona w C#

Jesli potrzebujesz bardziej skomplikowanego zarzadzania zyciem obiektow uzylbym konternera IoC: Najlepiej Castle Windsor. Dobre rzeczy slyszalem tez o NInject i o StructureMap ale ich nie uzywalem.
Od klas bazowych trzymalbym sie z daleka (to bardzo zly pomysl, stad moje poczatkowe zdziwienie). Object Builder jest kiepski. Jesli chcesz pozostac przy Microsoft rzuc okiem na Unity, ktore jest w zasadzie przepisana od podstaw, lepsza wersja OB.

konto usunięte

Temat: Klasa bazowa dla singletona w C#

Krzysztof K.:
Jesli potrzebujesz bardziej skomplikowanego zarzadzania zyciem obiektow uzylbym konternera IoC: Najlepiej Castle Windsor. Dobre rzeczy slyszalem tez o NInject i o StructureMap ale ich nie uzywalem.
Od klas bazowych trzymalbym sie z daleka (to bardzo zly pomysl, stad moje poczatkowe zdziwienie). Object Builder jest kiepski. Jesli chcesz pozostac przy Microsoft rzuc okiem na Unity, ktore jest w zasadzie przepisana od podstaw, lepsza wersja OB.

Castle'a znam, jest bardzo ciekawy.

Jedyny problem jaki z nim mieliśmy to wydajność - ponieważ nasza logika tworzy ogromną ilość obiektów (kilkanaście tysięcy), okazało się, że kod wykonywał się kilkanaście sekund. Używając "haka" klas bazowych zredukowaliśmy czas do mniej niż 2 sekund. W tym przypadku działa to pięknie. Co miałeś na myśli mówiąc, że to bardzo zły pomysł?
Sebastian Brózda

Sebastian Brózda programista ror/.net

Temat: Klasa bazowa dla singletona w C#

Krzysztof K.:
Jesli potrzebujesz bardziej skomplikowanego zarzadzania zyciem obiektow uzylbym konternera IoC: Najlepiej Castle Windsor. Dobre rzeczy slyszalem tez o NInject i o StructureMap ale ich nie uzywalem.
Od klas bazowych trzymalbym sie z daleka (to bardzo zly pomysl, stad moje poczatkowe zdziwienie). Object Builder jest kiepski. Jesli chcesz pozostac przy Microsoft rzuc okiem na Unity, ktore jest w zasadzie przepisana od podstaw, lepsza wersja OB.

Ja jeszcze polece Autofac'a. Co do ninjecta to rowniez go polecam, tutaj masz jeszcze linki do webcastow http://dimecasts.net/Casts/ByTag/Ninject oplaca sie obejrzec

pozdrawiam
Artur Kulik

Artur Kulik
http://www.dlafranka
.pl

Temat: Klasa bazowa dla singletona w C#

Sebastian H.:
Propnowałbym zrobić prostą fabrykę dla obiektów. Zrobiłbym prosty atrybut dla klas np. SingletonAttribute a potem taką fabrykę:

public class SingletonFactory
{
private Hashtable instances = new Hashtable();

private static readonly SingletonFactory instance = new SingletonFactory();

private SingletonFactory()
{

}

public T GetObjectInstance<T>() where T : class
{
Type type = typeof(T);
if(type.GetCustomAttributes(typeof(SingletonAttribute), true).Length > 0)
{
Object o = instances[type];
if(o != null)
{
return o as T;
}
else
{
T instance = type.InvokeMember(type.Name,
BindingFlags.CreateInstance |
BindingFlags.Instance |
BindingFlags.NonPublic,
null, null, null) as T;
instances.Add(type, instance);
return instance;
}
}
else
{
return Activator.CreateInstance<T>();
}
}

public static SingletonFactory Instance
{
get
{
return instance;
}
}
}

Klasy które będa tworzone jako singletony mogą mieć prywatny konstruktor.Sebastian H. edytował(a) ten post dnia 01.09.08 o godzinie 11:24

Czy te obiekty faktycznie beda tworzone jako singletony? Czy tylko fabryka bedzie gwarantowala, ze nie stworzy innej instancji, jesli jedna juz zrobila? Rozumiem, ze to jest pozadane rozwiazanie, ale nie mozna tego nazwac fabryka singletonow, bo "recznie" moge stworzyc inna instancje wybranej klasy (ktorej to jedna juz jest stworzona przez fabryke). Singleton, wedlug mojej wiedzy, powinien byc klasa, ktora gwarantuje, ze nie da sie miec wiecej jak jednej jej instancji. Tutaj tylko fabryka gwarantuje, ze "trzyma" jedna instancje i drugiej nie stworzy.

To takie akademickie rozwazanie...
Sebastian H.

Sebastian H. Starszy Programista,
VidCom.pl

Temat: Klasa bazowa dla singletona w C#

Artur Kulik:
Czy te obiekty faktycznie beda tworzone jako singletony? Czy tylko fabryka bedzie gwarantowala, ze nie stworzy innej instancji, jesli jedna juz zrobila? Rozumiem, ze to jest pozadane rozwiazanie, ale nie mozna tego nazwac fabryka singletonow, bo "recznie" moge stworzyc inna instancje wybranej klasy (ktorej to jedna juz jest stworzona przez fabryke). Singleton, wedlug mojej wiedzy, powinien byc klasa, ktora gwarantuje, ze nie da sie miec wiecej jak jednej jej instancji. Tutaj tylko fabryka gwarantuje, ze "trzyma" jedna instancje i drugiej nie stworzy.

To takie akademickie rozwazanie...

Nie wiem czy sie rozumiemy albo nie widać tego w moim kodzie, ale klasy które będa opatrzone atrybutem singleton będa tworzone przy użyciu domyślnego prywatnego konstruktora. Więc jak nie umieścimy innego konstrukta publicznego to jak chcesz utworzyć ręcznie taki obiekt. Na wstępie dostaniesz informację, że konstruktor nie jest dostępny.Sebastian H. edytował(a) ten post dnia 02.09.08 o godzinie 12:52
Artur Kulik

Artur Kulik
http://www.dlafranka
.pl

Temat: Klasa bazowa dla singletona w C#

Sebastian H.:
Nie wiem czy sie rozumiemy albo nie widać tego w moim kodzie, ale klasy które będa opatrzone atrybutem singleton będa tworzone przy użyciu domyślnego prywatnego konstruktora. Więc jak nie umieścimy innego konstrukta publicznego to jak chcesz utworzyć ręcznie taki obiekt. Na wstępie dostaniesz informację, że konstruktor nie jest dostępny.Sebastian H. edytował(a) ten post dnia 02.09.08 o godzinie 12:52

Ok, wszystko jasne. Problem tkwil w niedokladnym przestudiowaniu przeze mnie Twojego kodu (brak formatowania zrobil swoje).

Następna dyskusja:

Abstrakcyjna klasa bazowa w...




Wyślij zaproszenie do