Eksperci miesiąca

1
grzegorz.tworek
Senior
miesiąc
33
łącznie
814
2
dbsoft
Gość
miesiąc
29
łącznie
38
3
burzak
Guru
miesiąc
28
łącznie
1086
4
styrni
Top10
miesiąc
21
łącznie
4101
5
Bulax
Senior
miesiąc
21
łącznie
589

Z blogów MVP

Microsoft w Polsce

Statystyka

  • W tej chwili mamy:
    103 czytelników online
    58 605 zarejestrowanych
  • Do dziś zanotowaliśmy:
    46 037 803 odsłon
    65 009 odsłon / 24h
Microsoft Most Valuable Professional

Forum - Wątek

Idź do grupy:
Widok:
Autor

Wątek


jjohnny
Gość

wypowiedzi: 77
od: 2010-01-21
Modułowy framework - prośba o opinie 2010-01-02 (So) 15:33

Witam,

Po kilku latach programowania w .NET i utworzeniu kilkudziesięciu aplikacji zamierzam zebrać (przepisać) istniejący kod i stworzyć modułowy framework, który będzie używany do budowy kolejnych aplikacji. Ze względu na dużą różnorodność typów aplikacji, które pisze (asp.net, asp.net mvc, wpf, silverlight, usługi Windows, serwisy wcf) chcę, aby framework był niezależny od tych technologii. Stąd wynika główne założenie projektu: moduły będą zawierać jedynie encje, logikę biznesową oraz repozytoria. W przyszłości ewentualnie napisze takie modułowe frameworki dla konkretnych technologii (np.: asp.net mvc).

Schemat każdego modułu będzie składał się z interfejsu i domyślnej implementacji, która może być podmieniana przy użyciu IoC:

Modul1

Interface

Entities

Repositories (referencja do Modul1.Interface.Entities)

Services (referencja do Modul1.Interface.Entities oraz Modul1.Interface. Repositories)

Implementation

Entities (referencja do Modul1.Interface.Entities)

Repositories (referencja do Modul1.Interface.Entities oraz Modul1.Interface. Repositories)

Services (referencja do Modul1.Interface.Entities, Modul1.Interface. Repositories oraz Modul1.Interface. Services)

Aby umożliwić łatwe nadpisywanie poszczególnych funkcjonalności danego modułu użyty zostanie kontener IoC, a konkretnie UnityContainer (np.: po to aby dany moduł zapisywać dane do mysql zamiast mssql).

Rozważmy przykład modułu forum:

Forum

Interface

Entities (interfejsy: IForumEntity, IThreadEntity, IPostEntity)

Repositories (interfejs: IForumRepository)

Services (interfejs: IForumService)

Implementation

Entities (klasy: ForumEntity, ThreadEntity, PostEntity)

Repositories (klasa: ForumRepository)

Services (klasa: ForumService)

Co myślicie o takim rozwiązaniu?

Czy warto tworzyć interfejsy dla encji?

Zaloguj się, żeby odpowiedzieć

__Piotr__
Junior

wypowiedzi: 489
od: 2010-01-20

Odp: Modułowy framework - prośba o opinie 2010-01-03 (N) 16:55
Nie rozumiem po co interfejsy do encji. Rozumiem, że encja to pełni u Ciebie funkcje także logiki biznesowej a nie tylko jako czysty kontener informacji? Jeśli logike wrzucasz do serwisów to imho lepiej skorzystać ze wzorca projektowego Domain Model pattern.
Co do repozytorium to również korzystam z interfejsow do nich. Pamiętaj jednak, że repozytorium nie może zawierać żadnej logiki związanej z fizycznym zapisem danych. Repozytorium powinno korzystać z jakiegoś zewnętrznego interfejsu np. IDataContext, który będzie wstrzykiwany z konkretną implementacją. Mniej więcej coś takiego:

public interface IRepository
{
Add(T businessObject) where T:DomainObject;
FindById(Guid Id);
...
}

public class DataContextRepository:IRepository
{
public DataContextRepository(IDataContext repository){}
}

Co do modułowości w warstwie prezentacji polecam framework PRISM(dostępny na codeplex).
Zaloguj się, żeby odpowiedzieć

jjohnny
Gość

wypowiedzi: 77
od: 2010-01-21


Odp: Modułowy framework - prośba o opinie 2010-01-04 (Pn) 11:06
Zamierzam użyć wzorca Domain Model, stąd podział na encje, repozytoria i serwisy. Encje to tylko pojemniki na dane (ewentualnie jakieś właściwości wyliczane na podstawie innych właściwości danej encji), a cała logika biznesowa jest w serwisach.

Co do tych interfejsów to też mam wątpliowści :/
Jednak umnożliwiają one używanie dowolnych klas, bo jedyne wymaganie to implementacja danego interfejsu.

Załóżmy, że mam dwa moduły: wspomniany moduł Forum i moduł Security (służy do przypisywania i odczytywania uprawnien dla dowolnych encji).
Wtedy tworze projekt zawierajacy klase Forum, która implementuje dwa interfejsy IForumEntity (z modułu forum) oraz ISecuredEntity (z modułu Security).
Do obu modułów przekazuje obiekty klasy Forum.

Wtedy klasa repozytorium wyglada tak np.:

public interface IForumRepository
{
Add(IForumEntity forum);
IForumEntity GetById(Guid id);
}

Nie wiem czy to nie będzie trochę over-engineering :P

Można by tez zrobić rozwiązanie pośrednie i np w modułach takich jak Security uzyc interfejsow a takich jak Forum klas.
Zaloguj się, żeby odpowiedzieć

__Piotr__
Junior

wypowiedzi: 489
od: 2010-01-20



Odp: Modułowy framework - prośba o opinie 2010-01-04 (Pn) 13:54
Z frameworków\bibliotek polecam jeszcze:
MVC# - http://www.mvcsharp.org/
AutoMapper - http://www.codeplex.com/AutoMapper
Mapper przyda Ci się do mapowania obiektów biznesowoych na DTO w warstwie usług. Nie będzie musiał pisać nudnych maperów.
Microsoft Enterprise Library - m.in obsługa loggingu, monitoringu oraz scentralizowany system obsługi wyjątków. W dużych projektach naprawde się przydaje.

Co do interfejsów.
Ja u siebie mam klasę abstrakcyjną DomainModel który zawiera tylko Id, walidacje podstawową itp.
Następnie wszystkie obiekty biznesowe dziedziczą po tej klasię. Co ważne muszą być to obiekty typu POCO. Uważam, że warstwa biznesowa wyłącznie z takich klas powinna składać się.
W obiektach biznesowych trzymam i dane i logike biznesową. Z tego co rozumiem(opierając się na książkach Fowler'a) tak powinno projektować się warstwę biznesową.
Interfejsów używałbym bardziej jako rozszerzenia(typu IEncryptable itp), repozytorium, DAL itp.
Piszę teraz projekt niezależny od ORM, maksymalnie elastyczny i powiem tylko, że robi się z tego koszmar. Za pomocą stadrdowego podejścia oraz Entity Framework już dawno bym stworzył ten projekt. Ale takie akurat wymagania ma ten projekt...
Zaloguj się, żeby odpowiedzieć

jjohnny
Gość

wypowiedzi: 77
od: 2010-01-21




Odp: Modułowy framework - prośba o opinie 2010-01-04 (Pn) 21:30
Dzieki za te biblioteki!!

Kiedys intensywnie wykorzystywałem wzorzec Domain Model.
Za bardzo zaczął mi sie model rozrastać pod względem implementacji zachowania,
więc przeszedłem na DDD i logike upycham w serwisy albo wizytory, np.:

[Kod C#]
public static LockUserProfileResult LockUserProfile(string nick)
{
    try
    {
     
 
;
 
; using (TransactionScope ts = new TransactionScope())
     
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
; UserProfile userProfile = GetUserProfileByNick(nick, UserProfileIncludes.Empty);

     
 
;
 
;
 
;
 
;
 
;
 
; if (null == userProfile)
     
 
;
 
;
 
;
 
;
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; return new LockUserProfileResult.UserProfi
leNot
Exist
(
)
;
     
 
;
 
;
 
;
 
;
 
;
 
; }

     
 
;
 
;
 
;
 
;
 
;
 
; if (userProfile.Status == UserProfileStatus.Locked)
     
 
;
 
;
 
;
 
;
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; return new LockUserProfileResult.UserProfi
leAlr
eadyL
ocked
(
)
;
     
 
;
 
;
 
;
 
;
 
;
 
; }

     
 
;
 
;
 
;
 
;
 
;
 
; userProfile.Status = UserProfileStatus.Locked;
     
 
;
 
;
 
;
 
;
 
;
 
; SaveUserProfile(userProfile);

     
 
;
 
;
 
;
 
;
 
;
 
; ts.Complete();
     
 
;
 
;
 
;
 
;
 
;
 
; return new LockUserProfileResult.Success();
     
 
;
 
; }
    }
    catch (Exception ex)
    {
     
 
;
 
; return new LockUserProfileResult.ExceptionOccured
(ex
)
;
    }
}

Wywołanie metody serwisu zwraca odpowiednia klase result, która dziedziczy po abstrakcyjnej klasie bazowej LockUserProfileResult:

[Kod C#]
public abstract class LockUserProfileResult
    {
     
 
;
 
; public abstract void AcceptVisitor(ILockUserProfileRes
ultVi
sitor visitor);


     
 
;
 
; public interface ILockUserProfileResultVisitor
     
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
; void VisitSuccess(Success result);

     
 
;
 
;
 
;
 
;
 
;
 
; void VisitExceptionOccured(ExceptionOccured result);

     
 
;
 
;
 
;
 
;
 
;
 
; void VisitUserProfileNotExist(UserProfi
leNot
Exist result);

     
 
;
 
;
 
;
 
;
 
;
 
; void VisitUserProfileAlreadyLocked(User
Profi
leAlr
eadyL
ocked result);
     
 
;
 
; }
     
 
;
 
;

     
 
;
 
; public class Success : LockUserProfileResult
     
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
; public override void AcceptVisitor(ILockUserProfileRes
ultVi
sitor visitor)
     
 
;
 
;
 
;
 
;
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; visitor.VisitSuccess(this);
     
 
;
 
;
 
;
 
;
 
;
 
; }
     
 
;
 
; }


     
 
;
 
; public class UserProfileNotExist : LockUserProfileResult
     
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
; public override void AcceptVisitor(ILockUserProfileRes
ultVi
sitor visitor)
     
 
;
 
;
 
;
 
;
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; visitor.VisitUserProfileNotExist(this);
     
 
;
 
;
 
;
 
;
 
;
 
; }
     
 
;
 
; }


     
 
;
 
; public class UserProfileAlreadyLocked : LockUserProfileResult
     
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
; public override void AcceptVisitor(ILockUserProfileRes
ultVi
sitor visitor)
     
 
;
 
;
 
;
 
;
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; visitor.VisitUserProfileAlreadyLocked
(this
)
;
     
 
;
 
;
 
;
 
;
 
;
 
; }
     
 
;
 
; }


     
 
;
 
; public class ExceptionOccured : LockUserProfileResult
     
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
; private Exception _Exception = null;

     
 
;
 
;
 
;
 
;
 
;
 
; public ExceptionOccured(Exception exception)
     
 
;
 
;
 
;
 
;
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; _Exception = exception;
     
 
;
 
;
 
;
 
;
 
;
 
; }

     
 
;
 
;
 
;
 
;
 
;
 
; public Exception Exception
     
 
;
 
;
 
;
 
;
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; get
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; return _Exception;
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; }
     
 
;
 
;
 
;
 
;
 
;
 
; }

     
 
;
 
;
 
;
 
;
 
;
 
; public override void AcceptVisitor(ILockUserProfileRes
ultVi
sitor visitor)
     
 
;
 
;
 
;
 
;
 
;
 
; {
     
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
;
 
; visitor.VisitExceptionOccured(this);
     
 
;
 
;
 
;
 
;
 
;
 
; }
     
 
;
 
; }
    }

Mając obiekt rezult moge go przejść wizytorem:
[Kod C#]

LockUserProfileResult result = UserProfileService.LockUserProfile("johnny");

JakisTamWizytor visitor = new
JakisTamWizytor();
// klsa implementujaca interface
ILockUserProfileResultVisitor

result.AcceptVisitor(
visitor);

Bardzo wygodnie pisze mi sie w ten sposób aplikacje.

Zaloguj się, żeby odpowiedzieć

__Piotr__
Junior

wypowiedzi: 489
od: 2010-01-20





Odp: Modułowy framework - prośba o opinie 2010-01-04 (Pn) 21:46
Jeśli chodzi o źródło tzw. best practices polecam również 2 książki:
Microsoft® .NET: Architecting Applications for the Enterprise, Microsoft Press,
Patterns of Enterprise Application Architecture,Martin Fowler.

Druga pozycja to klasyka. Jednak pierwsza ma tą zaletę, że pokazuje jak pewne rzeczy zrobić w .NET. Naprawde bardzo dobrę źródlo informacji o pisaniu solidnego kodu.
Zaloguj się, żeby odpowiedzieć

andrew_sz
Senior

wypowiedzi: 698
od: 2010-01-21





Odp: Modułowy framework - prośba o opinie 2010-01-05 (Wt) 16:54
Z kontenerów to ja jeszcze polecam StructureMap.
Zaloguj się, żeby odpowiedzieć

biz
Junior

wypowiedzi: 175
od: 2010-01-21



Odp: Modułowy framework - prośba o opinie 2010-03-17 (Śr) 15:34

Tylko czy wtedy będzie to Domain Model czy raczej Anemic Domain Model? ;)

http://martinfowler.com/bliki/An

emicD
omain
Model
.html

Zaloguj się, żeby odpowiedzieć

jjohnny
Gość

wypowiedzi: 77
od: 2010-01-21


Odp: Modułowy framework - prośba o opinie 2010-01-04 (Pn) 11:14
Co do PRISMa to jak najbardziej, solidny framework!

Dla asp.net mvc w warstwie prezentacji przydało by się coś ciekawego.
Znalazłem to http://www.wynia.org/wordpress
/2008
/12
/aspnet
-mvc
-plugins
/ - ale żadna rewelacja.
Zaloguj się, żeby odpowiedzieć