我们正在为C#项目评估IoC容器,Unity和Castle.Windsor都很突出.我喜欢Unity的一件事(NInject和StructureMap也这样做)是明显如何构造它们的类型不必在IoC容器中注册.
有没有办法在Castle.Windsor做到这一点?我对Castle很公平.温莎要说它不这样做吗?有没有设计理由故意不这样做,或者是疏忽,还是只是没有被视为重要或有用?
我知道container.Register(AllTypes...在温莎,但这不是一回事.它不是完全自动化的,而且非常广泛.
为了说明这一点,这里有两个NUnit测试通过Unity和Castle.Windsor做同样的事情.Castle.Windsor失败了.:
namespace SimpleIocDemo
{
using NUnit.Framework;
using Castle.Windsor;
using Microsoft.Practices.Unity;
public interface ISomeService
{
string DoSomething();
}
public class ServiceImplementation : ISomeService
{
public string DoSomething()
{
return "Hello";
}
}
public class RootObject
{
public ISomeService SomeService { get; private set; }
public RootObject(ISomeService service)
{
SomeService = service;
}
}
[TestFixture]
public class IocTests
{
[Test]
public void UnityResolveTest()
{
UnityContainer container = new UnityContainer();
container.RegisterType<ISomeService, ServiceImplementation>();
// Root object needs no registration …Run Code Online (Sandbox Code Playgroud) .net castle-windsor ioc-container inversion-of-control unity-container
没有人喜欢我的第一个问题: 使用Unity for Work of Work/Repository模式创建Entity Framework对象
所以我设法把它改写成你可以阅读而不会入睡/失去生存意愿的东西.
我正在创建一个对象DataAccessLayer,它在构造函数中有2个接口:IUnitOfWork和IRealtimeRepository:
public DataAccessLayer(IUnitOfWork unitOfWork,
IRealtimeRepository realTimeRepository)
{
this.unitOfWork = unitOfWork;
this.realTimeRepository = realTimeRepository;
}
Run Code Online (Sandbox Code Playgroud)
现在,实现IRealtimeRepository的构造函数也接受IUnitOfWork参数:
public DemoRepository(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
Run Code Online (Sandbox Code Playgroud)
在Unity容器设置中,我然后添加两个实现:
container.RegisterType<IUnitOfWork, communergyEntities>();
container.RegisterType<IRealtimeRepository, DemoRepository>();
Run Code Online (Sandbox Code Playgroud)
会发生什么是Unity创建2个新的IUnitOfWork实例(实际上是一个实体框架数据上下文),一个用于DataAccessLayer构造函数,一个用于DemoRepository构造函数
由于这是针对工作单元模式,因此重用相同的实例非常重要.有任何想法吗?我之前已经问过类似的问题,但是没有被接受
在工作中,我们经常使用Unity.它的功能非常棒,但您使用的越多,配置文件越多,运行时问题就越多,您为每个测试项目重新创建统一配置的次数就越多.
因此,我们最终与具有翻过几个项目被复制,当谈到时间部署,你最终不得不追查你忘记添加到引用的DLL一个巨大的统一配置部分,但你只发现这些在运行时.不好玩.
我猜测有人遇到过这个问题而且有一个解决方案.理想情况下,我想弄清楚如何以一种使用约定优于配置的方式配置Unity,并减少运行时问题(即,庞大的配置文件).有人知道用最小配置实现Unity的好方法吗?
编辑:有一件事:我必须坚持只使用Unity.无法真正切换到Ninject等
我在WPF中使用带有Unity的PRISM 4 Navigation API.我有一个树视图,它启动一个RequestNavigate传递所选树节点的ID(GUID).
_regionManager.RequestNavigate(RegionNames.DetailRegion,
ViewNames.SiteView + "?ID=" + site.ID);
Run Code Online (Sandbox Code Playgroud)
在我的模块中,我已经注册了view/view-model,如下所示:
_container.RegisterType<SiteDetailsViewModel>();
_container.RegisterType<object, SiteDetailsView>(ViewNames.SiteView);
Run Code Online (Sandbox Code Playgroud)
当我从树视图中选择不同的节点时,DetailsRegion会按预期显示SiteDetailsView,但是当我想导航回同一节点时,会创建一个新的视图/视图模型.
我试图打破,IsNavigationTarget(NavigationContext navigationContext)但这种方法似乎永远不会被调用.
我哪里出错了?提前致谢.
我正在使用Unity来实例化一些对象,我发现无论我尝试什么,Unity都会为我的对象创建单例.
根据文档:http: //msdn.microsoft.com/en-us/library/dd203242.aspx#Y500
使用以下代码,我应该在每次接口解析时获得不同的实例.
IUnityContainer myContainer = new UnityContainer();
// Register a default (un-named) type mapping with a transient lifetime
myContainer.RegisterType<IMyObject, MyRealObject>();
// Following code will return a new instance of MyRealObject
myContainer.Resolve<IMyObject>();
Run Code Online (Sandbox Code Playgroud)
但相反,我得到一个单例实例.
以下是我的声明.Global.asax中
// This should get me a singleton
container.RegisterType<IRetailerService, RetailerService>(new ContainerControlledLifetimeManager(), new InjectionConstructor());
// This is the one giving me trouble.
container.RegisterType<IInStoreRetailersViewModelBuilder, InStoreRetailersViewModelBuilder>(new InjectionConstructor(container.Resolve<IRetailerService>()));
container.RegisterType<CollectController>(new InjectionConstructor(container.Resolve<IInStoreRetailersViewModelBuilder>()));
Run Code Online (Sandbox Code Playgroud)
调节器
private readonly IInStoreRetailersViewModelBuilder _inStoreRetailersViewModelBuilder;
public CollectController(IInStoreRetailersViewModelBuilder inStoreRetailersViewModelBuilder)
{
this._inStoreRetailersViewModelBuilder = inStoreRetailersViewModelBuilder;
}
public ActionResult Index()
{ …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Microsoft Unity在ASP.NET MVC 3应用程序中使用依赖注入工作.首先,我实现了自己的IDependencyResolver并在我的Global.asax文件中激活它,如下所示:
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
Run Code Online (Sandbox Code Playgroud)
我发现我不需要做任何其他事情来控制器注入(通过构造函数和[Dependency]属性)来工作.使用默认视图引擎,我还发现我可以使[Dependency]属性在标准视图中工作,但不能在布局视图中工作.是否有可能使布局视图也适用于此?
但是我实现了自己的视图引擎,该引擎继承自VirtualPathProviderViewEngine,它覆盖CreateView/CreatePartialView方法并返回我自己的自定义视图(实现IView).请参阅下面的自定义视图的Render方法:
public void Render(ViewContext viewContext, TextWriter writer) {
var webViewPage = DependencyResolver.Current.GetService(_type) as WebViewPage;
//var webViewPage = Activator.CreateInstance(_type) as WebViewPage;
if (webViewPage == null)
throw new InvalidOperationException("Invalid view type");
webViewPage.VirtualPath = _virtualPath;
webViewPage.ViewContext = viewContext;
webViewPage.ViewData = viewContext.ViewData;
webViewPage.InitHelpers();
WebPageRenderingBase startPage = null;
if (_runViewStartPages)
startPage = StartPage.GetStartPage(webViewPage, "_ViewStart", _viewStartFileExtensions);
var pageContext = new WebPageContext(viewContext.HttpContext, webViewPage, null);
webViewPage.ExecutePageHierarchy(pageContext, writer, startPage);
}
Run Code Online (Sandbox Code Playgroud)
使用注释掉的行我在视图中完全丢失了依赖注入,所以我将其更改为上面的行,这对于标准视图再次正常工作,但不适用于布局视图.如果您能告诉我如何修改上述内容以适用于布局视图,我会很感激吗?
最后我还试图让动作过滤器注入工作.我发现了两种不同的情况:
通过属性将过滤器应用于操作.
将其定义为全局过滤器,例如:
GlobalFilters.Filters.Add(new TestAttribute());
似乎都没有使用依赖性解析器.因此我需要做一些额外的工作.如果有更好的方法,请纠正我.为了启用第一个场景,我执行了以下操作:
public class UnityFilterAttributeFilterProvider : FilterAttributeFilterProvider …Run Code Online (Sandbox Code Playgroud) 对于以下"项目",我在解析Unity for DI时会遇到一个非常烦人且无法解释的错误.
InvalidOperationException - 无法构造LogWriter类型.您必须配置容器以提供此值.
?ex.Message; "依赖项的解析失败,类型= \"WindowsFormsApplication1.Performance \",name = \"(none)\".\ r \n发生异常时:解析时.\ r \n \nException是:InvalidOperationException - LogWriter类型不能是您必须配置容器以提供此值.\ r \n ---------------------------------- -------------\r\NAT异常的时间,该容器是:\ r \n\r \n解决WindowsFormsApplication1.Performance,(无)\ r \n解决参数\ "LW \" 构造WindowsFormsApplication1.Performance的(Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter LW,Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionManager EM)\ r \n解决Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter,(无)\r \n"
?ex.StackTrace; "在Microsoft.Practices.Unity.UnityContainer.DoBuildUp(类型t,对象存在,字符串名称,IEnumerable
1 resolverOverrides) in e:\\Builds\\Unity\\UnityTemp\\Compile\\Unity\\Unity\\Src\\UnityContainer.cs:line 515\r\n at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name, IEnumerable1 resolverOverrides)中的e:\ Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:485行\在电子r \ñ在Microsoft.Practices.Unity.UnityContainer.Resolve(T型,字符串名称,ResolverOverride [] resolverOverrides):\构建\统一\ UnityTemp \编译\统一\统一\ SRC\UnityContainer.cs:线173 \在电子r \ñ在Microsoft.Practices.Unity.UnityContainerExtensions.Resolve [T](IUnityContainer容器,ResolverOverride []重写):\构建\统一\ UnityTemp \编译\统一\统一\ SRC\UnityContainerExtensions.cs:线504\r \ñ在WindowsFormsApplication1.Form1.OnLoad(EventArgs的发送)在d:\ Devzone \任务处理\ WindowsFormsApplication1\Form1.cs中:行33"
在一个表格中:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
try
{
IUnityContainer …Run Code Online (Sandbox Code Playgroud) 嗨,我想在WPF MVVM应用程序中使用Unity容器.我没有使用Prism,因为它似乎很重.这是应用程序结构.我试图弄清楚如何解决视图到ViewModels和视图模型(服务)的依赖关系.
查看
MainWindow.xaml
CustomerList.xaml
CustomerDetail.xaml
BookList.xaml
BookDetail.xaml
Run Code Online (Sandbox Code Playgroud)
的ViewModels
MainViewModel
CustomerListViewModel
BoolListViewModel
BookDetailViewModel
CustomerDetailViewModel
Run Code Online (Sandbox Code Playgroud)
图书馆
ICustomerService (AddCustomer, SaveCustomer, GetCustomers, GetCustomer)
CustomerService:ICustomerService
IBookService (GetBooks, GetBook)
BookService:IBookService
IBookReserveService(Reserve, Return)
BookReserveService:IBookReserveService
Run Code Online (Sandbox Code Playgroud)
MainViewModel需要引用ICustomerService和IBookService
CustomerListViewModel需要引用ICustomerService
BoolListViewModel需要引用IBookService
BookDetailViewModel需要引用ICustomerService和IBookReserveService
CustomerDetailViewModel需要引用ICustomerService和IBookReserveService
我在每个视图模型中都有getter setter属性.
我遇到的问题是如何在WPF中使用依赖注入,特别是对于Views和ViewModel.我尝试使用Unity在一个工作正常的控制台应用程序中注册和解决.但我想了解如何为WPF应用程序做到这一点.我试过注册
container.RegisterType<ICustomerService, CustomerService>()
container.RegisterType<IBookReserveService, BookReserveService>()
container.RegisterType<IBookService, BookService>()
Run Code Online (Sandbox Code Playgroud)
并使用container.Resolve();
但我不知道如何判断哪个视图必须使用哪个视图模型并在需要时解决它们而不是应用程序启动时.此外,我不解决应用程序启动中的所有映射.应该在选择菜单(选择客户以查看详细信息,选择书籍以查看详细信息,保存客户,预订簿等)时执行此操作.
我读到的大部分内容都想使用IView和IViewModel.但不确定我是否理解其中的优势.
任何帮助是极大的赞赏.
我有以下代码
public abstract class A
{
public abstract string MethodA();
}
public class B : A
{
public override string MethodA()
{
return "Class B method";
}
}
public class C : A
{
public override string MethodA()
{
return "Class C method";
}
}
Run Code Online (Sandbox Code Playgroud)
我想使用服务定位器注册并解决具体实现.这可能吗?