我正在尝试将依赖注入与Windsor连接到标准的asp.net Web表单.我认为我已经使用HttpModule和CustomAttribute(下面显示的代码)实现了这一点,虽然解决方案似乎有点笨拙,并且想知道是否有更好的支持解决方案开箱即用Windsor?
这里有几个文件一起显示
// index.aspx.cs
public partial class IndexPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Logger.Write("page loading");
}
[Inject]
public ILogger Logger { get; set; }
}
// WindsorHttpModule.cs
public class WindsorHttpModule : IHttpModule
{
private HttpApplication _application;
private IoCProvider _iocProvider;
public void Init(HttpApplication context)
{
_application = context;
_iocProvider = context as IoCProvider;
if(_iocProvider == null)
{
throw new InvalidOperationException("Application must implement IoCProvider");
}
_application.PreRequestHandlerExecute += InitiateWindsor;
}
private void InitiateWindsor(object sender, System.EventArgs e)
{ …
Run Code Online (Sandbox Code Playgroud) 我看到很多文章都说IoC和DI有多棒,而且没有关于它为什么不那么好的文章,因为它可以使代码更复杂.我还看到IoC不应该是代码的核心部分,而是更多的库和插件.文章通常只是一个小参考,这两个模式如何使代码更复杂,但在细节上没有多少.这是我的问题 - 具体应该在哪些地方使用这些模式?
这是一个很好的主题:什么是控制反转?.如果你向下看,有一篇关于拼写检查的帖子和另一篇关于IoC如果只是一个拼写检查器可能不是很好用的帖子.作为一般准则,如果不使用IoC,我只有一个具体的接口类?意思是,我有IMyClass.然后只有实现IMyClass的具体MyClassA.我为什么要在那里使用IoC?
如果我有MyClassA,MyClassB和MyClassC,每个都实现IMyClass,那些可能是IoC正确的候选者吗?
从同一个帖子,有谁知道这篇文章意味着什么:
methodology design-patterns dependency-injection inversion-of-control
在我的引导程序中:
namespace Conduit.Mam.ClientServices.Common.Initizliaer
{
public static class Initializer
{
private static bool isInitialize;
private static readonly object LockObj = new object();
private static IUnityContainer defaultContainer = new UnityContainer();
static Initializer()
{
Initialize();
}
public static void Initialize()
{
if (isInitialize)
return;
lock (LockObj)
{
IUnityContainer container = defaultContainer;
//registering Unity for MVC
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
//registering Unity for web API
// GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
#region managers
container.RegisterType<ISettingsManager, SettingsManager>();
container.RegisterType<IMamDataManager, MamDataManager>();
container.RegisterType<IAppsDataManager, AppsDataManager>();
#endregion
if (!isInitialize)
{
isInitialize = true;
} …
Run Code Online (Sandbox Code Playgroud) 似乎每个人都在转向IoC容器.我曾试图"摸清"它一段时间,尽管我不想成为一个在高速公路上走错路的司机,但它仍然没有通过常识测试.让我解释一下,如果我的论点存在缺陷,请纠正/启发我:
我的理解:IoC容器应该在组合不同组件时让您的生活更轻松.这可以通过a)构造函数注入,b)setter注入和c)界面注入来完成.然后以编程方式或在容器读取的文件中"连接"它们.然后按名称召唤组件,然后在需要时手动投射.
我得不到的:
编辑 :( 更好的措辞) 为什么使用一个不是语言惯用的不透明容器,如果组件设计得当(使用IoC模式,松散耦合),你可以用更简洁的方式"连接"应用程序(imho) ?这个"托管代码"如何获得非平凡的功能?(我听过一些关于生命周期管理的提及,但我不一定能理解这比自己动手更好/更快.)
ORIGINAL:为什么要将所有组件存储在一个容器中,以与语言惯用的方式"连接起来",在按名称调用组件时使用相当于"goto labels"的东西,然后通过手动转换失去静态类型语言的许多安全优势,当你通过不执行它获得等效功能时,而是使用现代OO语言给出的所有很酷的抽象功能,例如编程到接口?我的意思是,实际上需要使用组件的部件必须知道它们在任何情况下都在使用它,并且在这里你将使用最自然,惯用的方式进行"连线" - 编程!
说,我有这样的类层次结构:
public interface IRepository { }
public class SomeSimpleRepository : IRepository {}
Run Code Online (Sandbox Code Playgroud)
现在我想用其他函数"装饰"SomeSimpleRepository
public class MoreAdvancedRespository : IRepository
{
private readonly IRepository _originalRepository;
public MoreAdvancedRespository(IRepository original)
{ }
}
Run Code Online (Sandbox Code Playgroud)
过了一会又一个......
public class TrickyRepository : IRepository
{
private readonly IRepository _originalRepository;
public TrickyRepository (IRepository original)
{ }
}
Run Code Online (Sandbox Code Playgroud)
现在,我需要完成绑定.在应用程序中,我需要使用MoreAdvancedRespository初始化TrickyRepository的实例.所以,我需要写一些类似的东西:
Bind<IRepository>().To<TrickyRepository>.With ??
Run Code Online (Sandbox Code Playgroud)
在这里我很困惑,我需要以某种方式说,采取MoreAdvancedRespository,但用SomeSimpleRepository初始化它.这是一种依赖关系链,必须针对一个接口进行解析.
有没有人对此提出建议?
警告,提前很长时间.
我最近一直在思考这个问题,我很难在这里找到令人满意的解决方案.我将使用C#和autofac作为示例.
IoC非常适合构建无状态服务的大型树.我解析服务并仅将数据传递给方法调用.大.
有时,我想将数据参数传递给服务的构造函数.这就是工厂的用途.而不是解析服务我解析它的工厂,并使用参数调用create方法来获取我的服务.多一点工作但还可以.
有时,我希望我的服务在一定范围内解析为同一个实例.Autofac提供了InstancePerLifeTimeScope()
非常方便的功能.它允许我总是在执行子树中解析到同一个实例.好.
有时候我想要结合两种方法.我想在构造函数中的数据参数,并具有作用域的实例.我还没有找到一种令人满意的方法来实现这一目标.
而不是将数据传递给构造函数,只需将其传递给Initialize
方法.
接口:
interface IMyService
{
void Initialize(Data data);
void DoStuff();
}
Run Code Online (Sandbox Code Playgroud)
类:
class MyService : IMyService
{
private Data mData;
public void Initialize(Data data)
{
mData = data;
}
public void DoStuff()
{
//...
}
}
Run Code Online (Sandbox Code Playgroud)
注册:
builder.RegisterType<MyService>().As<IMyService>().InstancePerLifetimeScope();
Run Code Online (Sandbox Code Playgroud)
用法:
var myService = context.Resolve<IMyService>();
myService.Init(data);
// somewhere else
var myService = context.Resolve<IMyService>();
Run Code Online (Sandbox Code Playgroud)
在第一次解析服务并调用Initialize后,我可以愉快地在同一个上下文中解析并获得相同的初始化实例.我不喜欢在调用之前Initialize
我有一个无法使用的对象的事实.在调用Initialize()之前,存在实例将被解析并在其他地方使用的危险.
这是一个包含对数据对象的引用的模式,而不是注入数据对象本身,我注入了holder对象.
接口:
interface IMyService
{
void DoStuff();
}
Run Code Online (Sandbox Code Playgroud)
类:
class MyService : …
Run Code Online (Sandbox Code Playgroud) c# dependency-injection inversion-of-control autofac object-lifetime
我试图找到一种方法来使用ASP.NET Web窗体控件的依赖注入.
我有很多控件可以直接创建存储库,并使用它们来访问和绑定数据等.
我正在寻找一种模式,我可以将存储库传递到外部控件(IoC),因此我的控件仍然不知道如何构建存储库以及它们来自何处等.
我不希望从我的控件中依赖IoC容器,因此我只希望能够使用构造函数或属性注入来构造控件.
(只是为了使事情复杂化,这些控件正在构建并在运行时由CMS放置在页面上!)
有什么想法吗?
我们想使用Unity for IOC.我所看到的是有一个全局静态服务(我们称之为IOCService)的实现,它包含对Unity容器的引用,该容器注册所有接口/类组合,每个类都询问该对象:给我一个实现为Ithis或IThat.
我经常看到这种模式不好的响应,因为它导致从ALL类到IOCService的依赖(而不是Unity容器,因为它只在IOCService内部知道).
但我经常看不到的是:替代方式是什么?
米歇尔
编辑:发现全局静态服务被称为服务定位器,将其添加到标题中.
自从我开始使用MVVM以来,这是我一直在努力解决的问题,首先是在WPF中,现在是在Silverlight中.
我使用IOC容器来管理Views和ViewModels的分辨率.视图往往是非常基本的,使用默认构造函数,但ViewModels倾向于访问实际服务,所有这些都是构造它们所必需的.同样,我使用IOC容器进行解析,因此注入服务不是问题.
成为问题的是使用IOC将所需数据传递给ViewModel.举个简单的例子,考虑一个允许编辑客户的屏幕.除了可能需要的任何服务之外,此屏幕的ViewModel还需要一个客户对象来显示/编辑客户的数据.
在进行任何类型的(非MVVM)库开发时,我认为通过构造函数传递类不变量是一个不可弯曲的规则.如果我需要特定于上下文的数据用于类构造时间并且所讨论的类是容器管理的,我倾向于使用抽象工厂*作为桥梁.在MVVM中,这看起来有点矫枉过正,因为大多数ViewModels都需要自己的工厂.
我尝试/考虑的一些其他方法包括(1)初始化/加载方法,其中我传递数据,这违反了通过构造函数强制类不变量的规则,(2)通过容器传递数据作为参数覆盖(Unity) ),以及(3)通过全局状态包(ugh)传递数据.
有哪些替代方法可以将特定于上下文的数据从一个ViewModel传递到另一个ViewModel?任何MVVM框架都能解决这个特定问题吗?
*它可能有自己的问题,比如需要在调用Container.Resolve()之间进行选择,或者不要让ViewModel容器管理.温莎城堡有一个很好的解决方案,但AFAIK没有其他框架.
编辑:
我忘了添加:如果您正在执行"View First"MVVM,我列出的某些选项甚至是不可能的,除非您先将数据传递给View然后再传递给ViewModel.
我正在使用可以被其他组件重用的类库.在这个类库中,我使用unity来进行依赖注入.对于这个类库,我创建了一个测试项目.调用者也获得了一个测试项目.我不确定的一件事是绑定的位置.我应该在类库中加入它还是应该从调用应用程序中执行此操作?
c# dependency-injection inversion-of-control unity-container
c# ×5
asp.net ×2
.net ×1
asp.net-mvc ×1
autofac ×1
decorator ×1
methodology ×1
mvvm ×1
ninject ×1
webforms ×1