- 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/
我开始认真考虑使用 IoC 容器会引发创建过度设计的解决方案(至少它会促使我尝试使用各种不必要的功能:)。 是时候将我的“IoC”反模式列表与社区列表同步了。 我短暂的经验告诉我们,在启动时每个应用程
我一直在阅读有关控制反转框架的内容,而我只是在玩弄这个问题:“我到底为什么需要一个框架来做到这一点?” 不要误解我的问题...该模式是我们程序员经常使用的,但是...一个功能齐全的框架可以做到这一点?
想要改进这篇文章?提供这个问题的详细答案,包括引文和解释为什么你的答案是正确的。没有足够细节的答案可能会被编辑或删除。 我正在尝试确定是否需要付出额外的努力来封装我的 IoC 容器。经验告诉我,我应该
有人建议我,在使用 IOC 容器时,我应该改变这个: class Foobar: IFoobar, IDisposable {}; 进入这个: interface IFoobar: IDisposab
《畜牧代码》播客第 68 期有人,http://herdingcode.com/herding-code-68-new-year-shenanigans/ ,表示 IOC 容器不适合使用 Python
我们正在使用 NInject 框架在我们的应用程序中实现 IoC/DI。我们有具有内部方法的内部类。要实现 IoC/DI,我们必须提取接口(interface)。但是如果我们在一个内部类中只有内部方法
Spring IOC 相关接口分析 1.BeanFactory Spring 中 Bean 的创建是典型的工厂模式,这一系列的 Bean 工厂,即 IOC 容器,为开发者管理对象之间的依赖关系提供了很
MEF is not an IoC container .不过好像是差不多 一个 IoC 容器。似乎我可以很容易地让 MEF 表现得像一个 IoC 容器(见下面的例子),而且让 MEF 成为一个完整的
只是想继续了解 IOC 的原则。 Q1:静态方法 - 具有静态辅助方法的实用程序类是否应该与 IOC 连接? 例如,如果我有一个带有许多静态方法的 HttpUtils 类,我是否应该尝试通过 IOC
众所周知,在asp.net Startup 类中有一个方法ConfigureServices,我们可以添加自定义服务。服务通过依赖注入(inject)提供。 ASP.NET Core includes
所以..我一直在深入研究 IoC 容器和服务定位器。 我认为 IoC 容器是 IoC 容器,而不是服务定位器,因为 您使用它的方式。您将服务定位器传递给需要依赖项的类,然后通过容器检索依赖项。另一方面
阅读许多有关这三个成语之间差异的帖子。但是比较困惑,然后我遇到了这篇文章: http://martinfowler.com/articles/injection.html 只是想看看我是否做对了。如果
我正在寻找用于 asp.net webapi 的 ioc 容器。我们正在寻找的几个关键功能如下 自定义生命周期 对网络请求生命周期的内置支持 在管理依赖项注册方面与 Web API 的良好集成。 最佳
我很难跟随 FP。当人们说“更惯用的风格”时,我必须明白:99% 的 Java 库不适用于 Kotlin 和 Scala 的 FP 惯用风格,对吧?好吧,我需要 Spring Boot 来快速启动 V
目录 1、Spring 1.1、简介 1.2、优点 1.3、组成 1.4、扩展 2、IO
重要提示:请注意,我并不是说单例具有私有(private)构造函数和静态实例变量(或有人建议使用静态类),而是单例在应用程序生命周期内从控制容器的反转返回相同的实例。 许多容器默认使用较短的生命周期。
Closed. This question needs to be more focused。它当前不接受答案。 想要改善这个问题吗?更新问题,使它仅关注editing this post的一个问题。
松耦合当然很棒,但我经常想知道使用 IoC 容器(例如 CaSTLe Windsor)动态连接的开销对紧耦合系统有什么影响? 我知道详细的答案将取决于 IoC 的用途,但我真的只是想了解 IoC 工作
我正在努力让 IOC 在远程处理场景中工作。我将我的应用程序服务器设置为发布通过 XML 配置的服务(SingleCall)。 众所周知,这就像这样: RemotingConfiguration.Co
我使用 IoC (DI) 方法并且通常有参数,这些参数由最低层(数据库层等)从配置设置(即连接字符串、静态值等)中读取。最好的方法是什么? 直接在这个最底层读取,即: string sendGridA
我是一名优秀的程序员,十分优秀!