Zaczynam od MVC3 i chcę korzystać z elastycznej architektury, więc przeczytałem dziesiątki blogów, książkę (Pro ASP.NET MVC 3), przeczytałem o zasadach SOLID i wreszcie dostał się do struktury aplikacji lubię (a przynajmniej tak mi się wydaje, tak daleko, bo nie zbudowali niczego na nim jeszcze):Używanie programu Ninject w architekturze aplikacji SOLID
W tej strukturze:
- Domain przechowuje klasy POCO i definiuje interfejsy usługi
- Services realizuje interfejsów usług i określa repozytoria interfejsy
- danych implementuje repozytoriów interfejsy
- WebUI i domeny korzystania z usług
- Usługi użyć repozytoriów
- WebUI, usług i danych zależy od domeny dla klas POCO
Głównym powodem używania domeny przy użyciu usług jest sprawdzanie unikalnych kluczy w metodach Validate klas POCO (IValidatable).
Zaczynam budować aplikację odniesienia z tej struktury, ale mam do czynienia do tej pory dwa problemy:
Używam projekt Data.Tests z testów jednostkowych dla repozytoriów, ale nie znalazłem sposobu na wstrzyknięcie (używając Ninject) implementacji usługi (w konstruktorze lub w inny sposób) na modelu, więc metoda sprawdzania poprawności może wywołać funkcję CheckUniqueKey w usłudze.
Nie znalazłem żadnego odniesienia na temat podpinania projektu Ninject do projektu TEST (wiele projektów WebUI).
Co staram się osiągnąć tutaj jest w stanie przejść z EF na coś innego jak DAPPER, po prostu zmieniając zestaw danych.
UPDATE
Teraz (od 09-sie-2011) Ninject działa, ale myślę, że czegoś brakuje.
Mam CustomerRepository z dwóch konstruktorów:
public class CustomerRepository : BaseRepository<Customer>, ICustomerRepository
{
// The repository usually receives a DbContext
public CustomerRepository(RefAppContext context)
: base(context)
{
}
// If we don't receive a DbContext then we create the repository with a defaulte one
public CustomerRepository()
: base(RefApp.DbContext())
{
}
...
}
Na TestInitialize:
// These are for testing the Repository against a test database
[TestInitialize()]
public void TestInitialize()
{
// Context used for tests
this.context = new RefAppContext();
// This is just to make sure Ninject is working,
// would have used: repository = new CustomerRepository(context);
this.kernel = NinjectMVC3.CreateKernel();
this.kernel.Rebind<ICustomerRepository>().To<CustomerRepository>().WithConstructorArgument("context", context);
this.repository = kernel.Get<ICustomerRepository>();
}
W klasie klientów:
public class Customer : IValidatableObject
{
...
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// I want to replace this with a "magic" call to ninject
CustomerRepository rep = new CustomerRepository();
Customer customer = rep.GetDupReferenceCustomer(this);
if (customer != null)
yield return new ValidationResult("Customer \"" + customer.Name + "\" has the same reference, can't duplicate", new [] { "Reference" });
}
...
}
Jaki byłby najlepszy sposób na wykorzystanie Ninject w tym scenariuszu?
Każda pomoc będzie bardzo ceniona.
ODPOWIEDŹ, coś
będę rozważać tę kwestię jako aswered tak daleko. Mogę sprawić, że Ninject będzie działał, ale wygląda na to, że osiągnięcie zasady Zanurzenia zależności (DIP) SOLID zajmie trochę więcej czasu.
Pod tym względem musiałem pogrupować domenę, usługi i dane, stworzę kolejne pytanie w innym czasie i utrzymam projekt na zwykły sposób.
Dziękuję wszystkim.
Zasugeruj usunięcie odniesienia Ninject i zmień je na DI, ponieważ odpowiedź nie będzie (i nie powinna się zmieniać w zależności od konkretnego kontenera). Dodałbym również architekturę lub znajdę kilka dodatkowych tagów. –
@Ruben masz rację, nie brzmi to całkiem poprawnie, aby użyć "Ninject" i "architektury aplikacji" na tym samym zdaniu, to właśnie w tym przypadku próbuję rozwiązać problem bardzo specyficzny dla Ninject. –
Ułożyłem aktualizację na nowe pytanie, ponieważ jest to zupełnie inny temat, który nie ma wiele wspólnego z pierwszym. W przeciwnym razie niewiele osób przeczyta twój nowy problem. –