- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
准备好一堵代码墙...这是一篇很长的文章,但它已经是我能读到的最详细的内容了。
回应Still lost on Repositories and Decoupling, ASP.NET MVC
我认为我开始越来越接近理解这一切。我正在努力习惯使用这个。这是我到目前为止所拥有的。
Project.Web (ASP.NET MVC 3.0 RC)
Project.Models (Domain Objects)
Membership.Member
Membership.IMembershipProvider
Project.Persistence (Fluent nHibernate)
使用 CaSTLe.Windsor
Membership.MembershipProvider : IMembershipProvider
我在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
);
}
}
}
现在,在 Project.Web
Global.asax
Application_Start
中,我有以下代码。
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Register the Windsor Container
Project.Persistence.IoC.Initialize();
}
现在,在 Project.Web.Controllers.MembershipController
中,我有以下代码。
[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);
}
所以我首先问..
我的 SessionFactory 像这样工作......
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();
}
所以基本上,在我的 Project.Persistence
层中,我像这样调用 SessionFactory ..
var session = SessionFactoryContainer.Instance.OpenSession()
我已经接近做到这一点了吗?我仍然很困惑 - 我觉得 ISessionFactory
应该是 CaSTLe.Windsor
的一部分,但我似乎不知道该怎么做。我也对在 Controller 中创建存储库的方式感到困惑。这是否意味着每次使用存储库时我都必须执行所有“映射”?这看起来会非常消耗资源。
最佳答案
首先是一些概念细节。在 ASP.NET MVC 应用程序中,页面请求的典型入口点是 Controller 。我们希望控制反转容器为我们解析 Controller ,因为这样 Controller 所具有的任何依赖项也可以通过将依赖项列为 Controller 构造函数中的参数来自动解析。
还困惑吗?这是完成所有设置后如何使用 IoC 的示例。我认为这样解释会让事情变得更容易!
public class HomeController : Controller
{
// lets say your home page controller depends upon two providers
private readonly IMembershipProvider membershipProvider;
private readonly IBlogProvider blogProvider;
// constructor, with the dependencies being passed in as arguments
public HomeController(
IMembershipProvider membershipProvider,
IBlogProvider blogProvider)
{
this.membershipProvider = membershipProvider;
this.blogProvider = blogProvider;
}
// so taking your Registration example...
[HttpPost]
public ActionResult Register( Web.Models.Authentication.Registration model)
{
if (ModelState.IsValid)
{
this.membershipProvider.CreateUser(model.Email, model.Password);
}
// If we got this far, something failed, redisplay form
return View(model);
}
}
请注意,您不必自己进行任何解析,您只需在 Controller 中指定依赖项是什么。您实际上也没有给出任何关于如何实现依赖项的指示 - 它都是解耦的。这很简单,没有什么复杂的:-)
希望此时您会问,“但是构造函数如何实例化?”这是我们开始设置 CaSTLe 容器的地方,并且我们完全在 MVC Web 项目(不是持久性或域)中完成此操作。编辑 Global.asax 文件,将 CaSTLe Windsor 设置为 Controller 工厂:
protected void Application_Start()
{
//...
ControllerBuilder.Current
.SetControllerFactory(typeof(WindsorControllerFactory));
}
...并定义 WindsorControllerFactory 以便您的 Controller 由 Windsor 实例化:
/// Use Castle Windsor to create controllers and provide DI
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IWindsorContainer container;
public WindsorControllerFactory()
{
container = ContainerFactory.Current();
}
protected override IController GetControllerInstance(
RequestContext requestContext,
Type controllerType)
{
return (IController)container.Resolve(controllerType);
}
}
ContainerFactory.Current()
方法是静态单例,返回已配置的 CaSTLe Windsor 容器。容器的配置指示 Windsor 如何解决应用程序的依赖关系。例如,您可能配置了一个容器来解析 NHibernate SessionFactory 和您的 IMembershipProvider。
我喜欢使用多个“安装程序”来配置我的 CaSTLe 容器。每个安装程序负责不同类型的依赖项,因此我有一个 Controller 安装程序、一个 NHibernate 安装程序、一个 Provider 安装程序.
首先我们有ContainerFactory:
public class ContainerFactory
{
private static IWindsorContainer container;
private static readonly object SyncObject = new object();
public static IWindsorContainer Current()
{
if (container == null)
{
lock (SyncObject)
{
if (container == null)
{
container = new WindsorContainer();
container.Install(new ControllerInstaller());
container.Install(new NHibernateInstaller());
container.Install(new ProviderInstaller());
}
}
}
return container;
}
}
...然后我们需要每个安装程序。首先是ControllerInstaller
:
public class ControllerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
AllTypes
.FromAssembly(Assembly.GetExecutingAssembly())
.BasedOn<IController>()
.Configure(c => c.Named(
c.Implementation.Name.ToLowerInvariant()).LifeStyle.PerWebRequest));
}
}
...这是我的 NHibernateInstaller
虽然它与你的不同,但你可以使用你自己的配置。请注意,每次解析时我都会重复使用相同的 ISessionFactory
实例:
public class NHibernateInstaller : IWindsorInstaller
{
private static ISessionFactory factory;
private static readonly object SyncObject = new object();
public void Install(IWindsorContainer container, IConfigurationStore store)
{
var windsorContainer = container.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(SessionFactoryFactory));
}
private static ISessionFactory SessionFactoryFactory()
{
if (factory == null)
{
lock (SyncObject)
{
if (factory == null)
{
var cfg = new Configuration();
factory = cfg.Configure().BuildSessionFactory();
}
}
}
return factory;
}
}
最后,您需要定义您的 ProvidersInstaller
:
public class ProvidersInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
var windsorContainer = container
.Register(
Component
.For<IMembershipProvider>()
.ImplementedBy<SubjectQueries>())
.Register(
Component
.For<IBlogProvider>()
.ImplementedBy<SubjectQueries>());
// ... and any more that your need to register
}
}
这应该是足够的代码来开始! 希望你仍然和我在一起,因为城堡容器的美丽很快就会变得明显。
当您在持久层中定义 IMembershipProvider
的实现时,请记住它依赖于 NHibernate ISessionFactory
。您需要做的就是:
public class NHMembershipProvider : IMembershipProvider
{
private readonly ISessionFactory sessionFactory;
public NHMembershipProvider(ISessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
}
请注意,由于 CaSTLe Windsor 正在创建 Controller 并将提供程序传递给 Controller 构造函数,因此提供程序将自动传递到 Windsor 容器中配置的 ISessionFactory
实现!
您永远不必担心再次实例化任何依赖项。您的容器会自动为您完成这一切。
最后,请注意,IMembershipProvider
应定义为您的域的一部分,因为它定义了您的域行为方式的接口(interface)。如上所述,处理数据库的域接口(interface)的实现被添加到持久层。
关于asp.net-mvc - MVC 应用程序中的 CaSTLe Windsor IoC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4401244/
我在调用 Resolve 时遇到异常: KernelException: Could not instantiate custom activator Inner Exception: {"Const
我的应用程序使用“SignalR”客户端/服务器通信框架。如果您不熟悉它,服务器端应用程序通常包含一个或多个“集线器”类(类似于 asmx 网络服务),每个类都提供可由客户端调用的方法。在启动期间,客
假设我有这样的组件 public class MyComponent { public MyComponent(string name) { } } 我基本上想让提供的构造函数
在 CaSTLe Windsor 场景中,我想检查我的容器是否注册了某个服务,并且基本上做 if (container.HasComponentFor()) { // resolve serv
我想知道是否有一些最佳实践来实现我需要的功能。 我有一个 Web 应用程序,它在启动期间通过反射扫描某些程序集(插件)并针对公共(public)内核注册它们的依赖项。 外部库可能需要相同的依赖项。 例
我想知道是否有一些最佳实践来实现我需要的功能。 我有一个 Web 应用程序,它在启动期间通过反射扫描某些程序集(插件)并针对公共(public)内核注册它们的依赖项。 外部库可能需要相同的依赖项。 例
是否有关于如何使用 CaSTLe Windsor 的自动事务管理的任何简单示例? documentation似乎缺少一些信息。我看到有用于 nHibernate、ActiveRecord 等的工具……
考虑这个例子: public class Factory { private List subFactories; public Factory(Lis
我正在将我们的项目从 .Net 2 升级到 .Net4.5,同时我将尽可能多的引用推送到 NuGet 并确保版本是最新的。 我在运行其中一项测试时遇到问题 测试类: public cl
当我开始使用 Windsor 时,我认为 DI 会很简单。现在它让我越来越困惑。 在我看来,存储库是一个具有单例生命周期的类。我应该有一个 FooRepository 实例来在应用程序的生命周期内将
我有一个接口(interface) ISession,其实例由不同的 session 工厂生成,具体取决于类所属的命名空间。 我的组件注册示例: IWindsorContainer container
我有一个看似简单的用例。有一个 ICsvReader 组件。让我们在这里简单地将它命名为 Reader。我们加载了一组已知的 CSV 文件,其中一些有标题,有些没有。目前有多个阅读器:Reader_S
这是我在 Global.asax 中的代码 WindsorContainer container = new WindsorContainer(); container.Register(Compo
在使用 ArrayResolver 时,如果我注册了一个接口(interface)的多个实现和一个依赖于所述接口(interface)数组的类,我希望数组解析器注入(inject)所有可以成功解析的接
有没有人有一些使用城堡 Windsor InstallerFactory 来订购安装程序的示例代码? 似乎无法在文档或其他地方找到它。 干杯 最佳答案 您只能使用 InstallerFactory与
documentation 中有说明你应该总是让拦截器 transient 。如果我有这个示例代码; //register interceptor container.Register(Classes
我有一点问题。我在 CaSTLe Windsor IOC Container 工作。现在我想做的只是弄乱一些 AOP 原则,而我特别想做的是基于方法名称执行一些日志记录。我一直在研究拦截器,目前我正在
有人对使用 CaSTLe DynamicProxy 拦截属性的更好方法有什么建议吗? 具体来说,我需要我正在拦截的 PropertyInfo,但它不是直接在 IInvocation 上,所以我要做的是
使用 ArrayResolver 时,如果我注册了多个实现相同接口(interface)的依赖项,并且我已经注册了依赖于这些依赖项数组的类,那么人们会期望 ServiceOverrides 受到尊重并
如何使用 Windsor 容器将 appSettings 条目的值(来自 app.config 或 web.config)注入(inject)服务?如果我想将 Windsor 属性的值注入(injec
我是一名优秀的程序员,十分优秀!