Schloss Windsor IoC in einer MVC-Anwendung
Bereiten Sie für eine Wand-code... Es ist eine lange Lesen, aber es ist so ausführlich wie ich kann.
In Reaktion auf Immer noch verloren auf Repositories und Entkopplung ASP.NET MVC
Ich denke ich mich ab, um näher zu verstehen das alle.
Ich versuche mit diesem. Hier ist was ich habe, so weit.
Projekt
Projekt.Web - (ASP.NET MVC 3.0 RC)
- Projekt Verwendet.Modelle
- Projekt Verwendet.Persistenz
Projekt
Projekt.Modelle (Domain Objects)
Membership.Member
Membership.IMembershipProvider
Projekt
Projekt.Persistenz (Fluent nHibernate)
- Projekt Verwendet.Modelle
- Verwendet Burg.Kern
-
Verwendet Burg.Windsor
-
Membership.MembershipProvider : IMembershipProvider
Habe ich die folgende Klasse in Project.Persistence
using Castle.Windsor;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
namespace Project.Persistence
{
public static class IoC
{
private static IWindsorContainer _container;
public static void Initialize()
{
_container = new WindsorContainer()
.Install(
new Persistence.Containers.Installers.RepositoryInstaller()
);
}
public static T Resolve<T>()
{
return _container.Resolve<T>();
}
}
}
namespace Persistence.Containers.Installers
{
public class RepositoryInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component
.For<Membership.IMembershipProvider>()
.ImplementedBy<Membership.MembershipProvider>()
.LifeStyle.Singleton
);
}
}
}
Nun, in Project.Web
Global.asax
Application_Start
, ich habe den folgenden code.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
//Register the Windsor Container
Project.Persistence.IoC.Initialize();
}
Nun dann, in Project.Web.Controllers.MembershipController
ich habe den folgenden code.
[HttpPost]
public ActionResult Register( Web.Models.Authentication.Registration model)
{
if (ModelState.IsValid)
{
var provider = IoC.Resolve<Membership.IMembershipProvider>();
provider.CreateUser(model.Email, model.Password);
}
//If we got this far, something failed, redisplay form
return View(model);
}
Also Frage ich erstmal..
Bin ich auf dem richtigen Weg?
Wie kann ich ein Schloss.Windsor für meine ISessionFactory
Habe ich meine SessionFactory arbeiten wie diese ...
namespace Project.Persistence.Factories
{
public sealed class SessionFactoryContainer
{
private static readonly ISessionFactory _instance = CreateSessionFactory();
static SessionFactoryContainer()
{
}
public static ISessionFactory Instance
{
get { return _instance; }
}
private static ISessionFactory CreateSessionFactory()
{
return Persistence.SessionFactory.Map(@"Data Source=.\SQLEXPRESS;Initial Catalog=FluentExample;Integrated Security=true", true);
}
}
}
namespace Project.Persistence
{
public static class SessionFactory
{
public static ISessionFactory Map(string connectionString, bool createSchema)
{
return FluentNHibernate.Cfg.Fluently.Configure()
.Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008
.ConnectionString(c => c.Is(connectionString)))
.ExposeConfiguration(config =>
{
new NHibernate.Tool.hbm2ddl.SchemaExport(config)
.SetOutputFile("Output.sql")
.Create(/* Output to console */ false, /* Execute script against database */ createSchema);
})
.Mappings(m =>
{
m.FluentMappings.Conventions.Setup(x =>
{
x.AddFromAssemblyOf<Program>();
x.Add(FluentNHibernate.Conventions.Helpers.AutoImport.Never());
});
m.FluentMappings.AddFromAssemblyOf<Mapping.MembershipMap>();
}).BuildSessionFactory();
}
Also im Grunde, in meinem Project.Persistence
Ebene, nenne ich die SessionFactory wie diese..
var session = SessionFactoryContainer.Instance.OpenSession()
Bin ich auch immer in der Nähe zu tun, dieses Recht? Ich bin immer noch verwirrt - ich fühle mich wie der ISessionFactory
sollte Teil Castle.Windsor
, aber ich kann nicht scheinen, um herauszufinden, wie das zu tun. Ich bin verwirrt darüber, wie ich am erstellen Repository in den Controller. Bedeutet das, dass ich zu tun haben alle die 'mapping' jedes mal, wenn ich das Repository? Das scheint, wie es wäre sehr ressourcenintensiv.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zunächst einige konzeptionelle details. In einem ASP.NET MVC-Anwendung der typischen Einstieg für eine Anforderung der Seite ist ein controller. Wir wollen, dass die Inversion of Control container zur Lösung von Controllern für uns, weil dann alle Abhängigkeiten, die Controller kann auch automatisch gelöst werden, einfach durch die Auflistung der Abhängigkeiten als Parameter in der Controller-Konstruktoren.
Verwirrt? Hier ist ein Beispiel, wie Sie verwenden würden, IoC, nachdem es alle set up. Ich denke, zu erklären, es auf diese Weise macht die Dinge einfacher!
Beachten Sie, dass Sie nicht zu tun hatten jede Lösung sich selbst, Sie haben eben angegeben, in der controller, was die Abhängigkeiten sind. Noch haben Sie eigentlich irgendwelche Hinweise, wie die Abhängigkeiten implementiert werden - es ist alles entkoppelt. Es ist sehr einfach, es gibt nichts kompliziert hier 🙂
Hoffentlich werden Sie an diesem Punkt Fragen: "aber wie kommt der Konstruktor bekommen instanziiert?" Dies ist, wo wir beginnen, legen Sie Ihre Burg-container, und wir tun dies ganz im MVC-Web - Projekt (nicht-Persistenz oder-Domäne). Bearbeiten Sie die Globalen.asax-Datei, Einstellung von Schloss Windsor zu handeln, wie der controller factory:
...und definieren Sie die WindsorControllerFactory, so dass Sie Ihre Controller instanziiert von Windsor:
Den
ContainerFactory.Current()
- Methode ist static, singleton, gibt eine konfiguriert Castle Windsor container. Die Konfiguration des Containers weist Windsor, um eine Lösung für Ihre Anwendung Abhängigkeiten. So zum Beispiel, haben Sie vielleicht einen container konfiguriert zu beheben, die NHibernate SessionFactory, und Ihre IMembershipProvider.Ich wie konfigurieren, meine Burg, container mit mehreren "Installateure". Jeder Installateur ist verantwortlich für eine andere Art von Abhängigkeit, so würde ich einen Controller installer, eine NHibernate installer, eine Anbieter installer zum Beispiel.
Erstens haben wir die ContainerFactory:
...und dann brauchen wir jede der Installateure. Die
ControllerInstaller
erste:... und hier ist mein
NHibernateInstaller
obwohl es anders ist zu verkaufen, können Sie Ihre eigene Konfiguration. Beachten Sie, dass ich erneut dieselbeISessionFactory
Beispiel jedes mal, wenn eines gelöst ist:Und schließlich werden Sie wollen, definieren Sie Ihre
ProvidersInstaller
:Dies sollte genug code, um gehend zu erhalten! Hoffentlich bist du immer noch mit mir, wie die Schönheit des Schlosses container wird offensichtlich sehr kurz.
Beim definieren der Umsetzung Ihrer
IMembershipProvider
in der Persistenz-Schicht, denken Sie daran, dass es eine Abhängigkeit von der NHibernateISessionFactory
. Alles, was Sie tun müssen, ist dieses:Beachten Sie, dass Schloss Windsor, ist das erstellen eigener Controller und die Anbieter weitergeleitet, um Ihre controller-Konstruktor, der Anbieter automatisch weitergeleitet wird, die
ISessionFactory
Implementierung konfiguriert werden, in Ihrem Windsor container!Müssen Sie nie sorgen über die Instanziierung alle Abhängigkeiten wieder. Ihr container übernimmt alles automatisch für Sie.
Schließlich ist zu beachten, dass die
IMembershipProvider
sollte definiert werden als Teil der Domäne, wie es die Definition der Schnittstelle, wie Sie Ihre domain Verhaltensweisen. Wie oben erwähnt, die Umsetzung Ihrer domain interfaces, die sich mit den Datenbanken Hinzugefügt werden, um die Persistenz-Schicht.Vermeiden Sie die Verwendung einer statischen IoC-Klasse wie dieses. Indem du dies tust, bist du mit dem container als service-locator, so dass Sie nicht das erreichen der vollen Entkopplung der inversion of control. Sehen dieser Artikel für weitere Erläuterungen über dieses.
Schauen Sie sich auch Scharfe Architektur, die best practices für ASP.NET MVC, NHibernate und Windsor.
Wenn Sie Zweifel haben über den Lebenszyklus der container selbst, siehe Die Verwendung von IoC Containern; speziell Windsor