没有人喜欢我的第一个问题: 使用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很长一段时间,但我一直使用它与构造函数注入.为了减少我必须注入到我的视图模型中的类的数量(因为我的命令依赖于它们),我想我会尝试创建一个使用Property Injection的概念,从而消除对大型构造函数参数列表的要求.这是场景......
我正在创建一个视图模型,其中的命令位于以某种方式使用/更新软件视图模型的属性上.我希望将View Model的实例传递给View Models属性上的Commands的构造函数.例如
public MainViewModel
{
public MainViewModel()
{
Customers = new ObservableCollection<CustomerViewModel>();
}
[Depedency("LoadCommand")]
public ICommand LoadCustomersCommand { get; set; }
public ObservableCollection<CustomerViewModel> Customers { get; private set; }
}
public LoadCustomersCommand : ICommand
{
public LoadCustomersCommand(MainViewModel mainViewModel)
{
//Store view model for later use
}
//... implementation
}
//Setup code in App.Xaml
IUnityContainer unityContainer = new UnityContainer();
unityContainer.RegisterType<ICommand, LoadCommand>("LoadCommand");
unityContainer.RegisterType<MainViewModel>(new ContainerControlledLifetimeManager());
Run Code Online (Sandbox Code Playgroud)
当我解析MainViewModel类时,我得到一个StackOverflow异常(如果Visual Studio完全回来的话).现在我希望Unity首先创建一个MainViewModel实例,因为它基本上是一个单例,然后查看View Model的实例并创建在新创建的MainViewModel中传递的Command,但显然我错了.
有任何想法吗?
我想明确"释放"Unity解析的对象实例.我希望Teardown方法应该完全用于此,所以我尝试了这样的事情:
container.RegisterType(typeof(IMyType), typeof(MyType),
new MyLifetimeManager());
var obj = container.Resolve<IMyType>();
...
container.Teardown(obj);
Run Code Online (Sandbox Code Playgroud)
MyLifetimeManager存储对象实例HttpContext.Current.Items.我希望该Teardown方法将调用RemoveValue生命周期管理器并释放MyType实例和生命周期管理器实例.它不起作用.首先RemoveValue是没有调用,如果我再次调用,Resolve<IMyType>我将获得先前解析的实例.
Teardown方法应该怎么办?尽管有他的终身经理,我怎么能释放对象?
编辑:
如果Teardown没有发布实例,谁呢?谁打电话RemoveValue给终身经理?
对于以下"项目",我在解析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.但不确定我是否理解其中的优势.
任何帮助是极大的赞赏.
我们目前正在运行一个mvc3 webapp,本周早些时候我们尝试升级到mvc4,但是在我们发布网站之后,w3wp.exe开始吃大量内存(> 2gb)并在应用程序池上获得超时.
我们使用Unity(最新版本)和unity.mvc3,我们使用unity.mvc3中的特殊生命周期管理器来处理dbcontext.
我们使用ANTS内存分析器搜索问题,但找不到任何问题.只有实时网站似乎遇到了这个问题.
有没有人在这里有一些指示?
我有一个带逆变型参数的接口,比如说IFoo:
interface IFoo<in T> {}
Run Code Online (Sandbox Code Playgroud)
现在我有三个班:
class B {}
class D : B {}
class Foo : IFoo<B> {}
Run Code Online (Sandbox Code Playgroud)
如果我这样注册他们
container.RegisterType<IFoo<B>, Foo>();
Run Code Online (Sandbox Code Playgroud)
...然后尝试解决IFoo<D>,它失败,因为我没有真正注册IFoo<D>或IFoo<>
.很明显.
我当前的解决方案是迭代Registrations,找到RegisteredType可以从解析类型(IFoo<D>在我的情况下)分配的注册然后解析它的MappedToType类型.
问题很简单:有更好的方法吗?任何意见,将不胜感激.
谢谢.
编辑:
多一点背景.
我有一些映射器.
IMapper<in TSource, in TDest> : IMapper // IMapper is non-generic
{
void Map(TSource source, TDest dest);
}
Run Code Online (Sandbox Code Playgroud)
我想只登记基础映射器(其中TSource是IEnumerable<T>),并能够解决此映射为每一个实现类型IEnumerable<T>,例如用于T[]:
object source = GetSource(); // runtime type is T[] …Run Code Online (Sandbox Code Playgroud) 我使用EntityFramework和实施了一堆后台作业类的通用存储库和单元的工作模式.使用Unity DI创建作业类,以便可以向它们注入依赖项,这些依赖项主要是存储库和UnitOfWork对象.存储库和工作单元应共享EF DbContext.
一个常见的工作看起来像这样:
public class CommonJob : IJob, IDisposable
{
private IRepo<SomeEntity> _repo;
private IUnitOfWork _uow;
public CommonJob(IRepo<SomeEntity> repo, IUnitOfWork uow)
{
_repo = repo;
_uow = uow;
}
public void RunJob()
{
// do stuff here
}
public void Dispose()
{
_uow.Commit();
_uow.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
所有工作都在新任务中运行,就像这样
Task.Factory.StartNew(() => {
// container is UnityContainer
var job = container.Resolve<CommonJob>();
job.RunJob();
job.Dispose();
});
Run Code Online (Sandbox Code Playgroud)
我已经使用Unity注册了工作单元和存储库PerThreadLifetimeManager,认为这样可以在一个任务(以及一个作业对象)的上下文中共享已注册的实例,但不能在外部.
我遇到的问题是,有时工作会注入被处理的对象,这显然不是很好.我一直在阅读Task.Factory.StartNew()并不总是使用新线程.这是否意味着PerThreadLifetimeManager将在任务之间共享对象?如果这是真的,有没有另一种方法来统一管理对象生命周期,这将允许每个任务孤立地工作,无论它运行的线程是什么?
编辑:
虽然下面选择的答案将实现相同的目的,但我最终使用HierarchicalLifetimeManager和子容器来实现每个作业的依赖性隔离.
这是一个例子: …
c# dependency-injection .net-4.0 unity-container task-parallel-library
在Unity中,据我所知,我可以使用以下两个选项来注册单例实例:
IConfiguration globalConfig = new Configuration();
container.RegisterInstance<IConfiguration>(globalConfig);
container.RegisterType<IConfiguration, Configuration>(new ContainerControlledLifetimeManager());
Run Code Online (Sandbox Code Playgroud)
这两种方式有什么区别吗?注册单例实例的首选方法是什么?
unity-container ×10
c# ×5
.net ×4
.net-4.0 ×1
asp.net ×1
generics ×1
mvvm ×1
singleton ×1
unit-of-work ×1
wpf ×1