我IRespository在以下代码中注册了两次(带名字):
// Setup the Client Repository
IOC.Container.RegisterType<ClientEntities>(new InjectionConstructor());
IOC.Container.RegisterType<IRepository, GenericRepository>
("Client", new InjectionConstructor(typeof(ClientEntities)));
// Setup the Customer Repository
IOC.Container.RegisterType<CustomerEntities>(new InjectionConstructor());
IOC.Container.RegisterType<IRepository, GenericRepository>
("Customer", new InjectionConstructor(typeof(CustomerEntities)));
IOC.Container.RegisterType<IClientModel, ClientModel>();
IOC.Container.RegisterType<ICustomerModel, CustomerModel>();
Run Code Online (Sandbox Code Playgroud)
但是当我想要解决这个问题(使用IRepository)时,我必须像这样做一个手动解决方案:
public ClientModel(IUnityContainer container)
{
this.dataAccess = container.Resolve<IRepository>(Client);
.....
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是在构造函数中解析它(就像IUnityContainer).我需要一些方法来说明要解析的命名类型.
这样的事情:( 注意:不是真正的代码)
public ClientModel([NamedDependancy("Client")] IRepository dataAccess)
{
this.dataAccess = dataAccess;
.....
}
Run Code Online (Sandbox Code Playgroud)
有没有办法让我的假代码工作?
Unity依赖注入容器似乎是一个众所周知的问题,其中SynchronizedLifetimeManager经常会导致Monitor.Exit方法抛出SynchronizationLockException,然后捕获并忽略它.这对我来说是一个问题,因为我喜欢使用Visual Studio进行调试以打破任何抛出的异常,所以每次我的应用程序启动时,我都会无缘无故地多次打破这个异常.
如何防止抛出此异常?
无论在Web上的其他地方提到此问题,建议通常都涉及更改调试器设置以忽略它.这类似于去看医生并且说:"医生,医生,当我举起它时,我的手臂疼,"被告知,"好吧,停止提高它." 我正在寻找一种解决方案,可以阻止异常被抛出.
SetValue方法中发生异常,因为它假设首先调用GetValue,并调用Monitor.Enter.但是,LifetimeStrategy和UnityDefaultBehaviorExtension类都会定期调用SetValue而不调用GetValue.
我宁愿不必更改源代码并维护我自己的Unity版本,所以我希望有一个解决方案,我可以在容器中添加一些扩展,策略或策略的组合,以确保,如果生命周期管理器是一个SynchronizedLifetimeManager,GetValue始终先调用.
我刚开始学习DI(我正在研究WPF/Silverlight,但我有计划转向ASP.NET).在我从互联网上阅读了一些DI文章之后,有两个我感兴趣的框架,MEF和Unity.我想知道它们之间的真实世界有什么不同,哪一个是好的.
在跟进基耶斯洛夫的说法是温莎确实比其他国际奥委会的多很多,我想了解这些国际奥委会如何叠起来反对对方,这温莎城堡带来的好处/附加设施.
有比较吗?有人可以帮助我理解Castle Windsor提供的其他IoC附加功能
structuremap dependency-injection castle-windsor ioc-container unity-container
在尝试学习Unity时,我一直看到以下代码覆盖GetControllerInstanceMVC:
if(!typeof(IController).IsAssignableFrom(controllerType)) { ... }
Run Code Online (Sandbox Code Playgroud)
在我看来,这基本上是一种非常复杂的写作方式
if(controllerType is IController) { ... }
Run Code Online (Sandbox Code Playgroud)
我理解,存在之间的细微差别is和IsAssignableFrom,即IsAssignableFrom不包括投转换,但我在努力了解实际情况下这种差别的含义.
什么时候选择IsAssignableFrom结束有意义is?它会有什么不同GetControllerExample?
if (!typeof(IController).IsAssignableFrom(controllerType))
throw new ArgumentException(...);
return _container.Resolve(controllerType) as IController;
Run Code Online (Sandbox Code Playgroud) 我正在使用IoC框架,我选择使用Unity.我还没有完全理解的一件事是如何更深入地解析应用程序中的对象.我怀疑我当时还没有灯泡可以说清楚.
因此,我尝试在psuedo'ish代码中执行以下操作
void Workflow(IUnityContatiner contatiner, XPathNavigator someXml)
{
testSuiteParser = container.Resolve<ITestSuiteParser>
TestSuite testSuite = testSuiteParser.Parse(SomeXml)
// Do some mind blowing stuff here
}
Run Code Online (Sandbox Code Playgroud)
所以testSuiteParser.Parse执行以下操作
TestSuite Parse(XPathNavigator someXml)
{
TestStuite testSuite = ??? // I want to get this from my Unity Container
List<XPathNavigator> aListOfNodes = DoSomeThingToGetNodes(someXml)
foreach (XPathNavigator blah in aListOfNodes)
{
//EDIT I want to get this from my Unity Container
TestCase testCase = new TestCase()
testSuite.TestCase.Add(testCase);
}
}
Run Code Online (Sandbox Code Playgroud)
我可以看到三个选项:
[编辑]我不清楚的一件事是我想为foreach语句的每次迭代创建一个新的测试用例实例.上面的示例需要解析测试套件配置并填充测试用例对象的集合
我有一个MVC 3 Web应用程序,我使用Entity Framework进行数据访问.此外,我简单地使用了存储库模式,例如,所有与产品相关的东西都在"ProductRepository"中处理,所有与User相关的东西都在"UserRepository"中处理.
因此,我使用UNITY容器来创建DataContext的单例实例,我将其注入每个存储库.快速搜索Google,每个人都建议您不要使用DataContext的单例实例,因为它可能会在将来给您带来一些内存泄漏.
所以,受这篇文章的启发,为每个Web请求创建一个DataContext的单例实例就是答案(如果我错了,请纠正我!)
但是,UNITY不支持"Per-web-request"终身经理.但是,可以实现自己的自定义生命周期管理器,它可以为您处理此问题.实际上,这篇文章对此进行了讨论:
Unity中的Singleton Per Call上下文(Web请求)
问题是,我现在已经实现了上面帖子中描述的自定义生命周期管理器,但我不确定这是否是这样做的方法.我也想知道在提供的解决方案中处理datacontext实例的位置?我错过了什么吗?
实际上有更好的方法来解决我的"问题"吗?
谢谢!
以下是我的Global.asax,Controller和Repository的片段.这清楚地说明了我的实施情况.
Global.asax中
var container = new UnityContainer();
container
.RegisterType<ProductsRepository>(new ContainerControlledLifetimeManager())
.RegisterType<CategoryRepository>(new ContainerControlledLifetimeManager())
.RegisterType<MyEntities>(new PerResolveLifetimeManager(), dbConnectionString)
Run Code Online (Sandbox Code Playgroud)
调节器
private ProductsRepository _productsRepository;
private CategoryRepository _categoryRepository;
public ProductsController(ProductsRepository productsRepository, CategoryRepository categoryRepository)
{
_productsRepository = productsRepository;
_categoryRepository = categoryRepository;
}
public ActionResult Index()
{
ProductCategory category = _categoryRepository.GetProductCategory(categoryId);
.
.
.
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_productsRepository.Dispose();
_categoryRepository.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
产品库
public class ProductsRepository : IDisposable
{
private …Run Code Online (Sandbox Code Playgroud) entity-framework ioc-container unity-container asp.net-mvc-3
我正在使用Unity for Dependencies Injection并使用Identiy Provider来管理用户登录,注册,电子邮件确认等.
当我尝试注册用户时,我遇到了这个问题:
当前类型Microsoft.Owin.Security.IAuthenticationManager是一个接口,无法构造.你错过了类型映射吗?
我不知道如何在我的Unity容器中注册此接口(IAuthenticationManager).
我尝试使用此代码注册接口,但如果我把它,我还有其他问题:
没有注册IUserTokenProvider.
container.RegisterType<HttpContextBase>(
new InjectionFactory(_ => new HttpContextWrapper(HttpContext.Current)));
container.RegisterType<IOwinContext>(new InjectionFactory(c => c.Resolve<HttpContextBase>().GetOwinContext()));
container.RegisterType<IAuthenticationManager>(
new InjectionFactory(c => c.Resolve<IOwinContext>().Authentication));
Run Code Online (Sandbox Code Playgroud)
我把一些应用程序的代码(如果我不使用Unity,一切正常):
的AccountController
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
Run Code Online (Sandbox Code Playgroud)
IdentityConfig.cs
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options,
IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail …Run Code Online (Sandbox Code Playgroud) 几天前,我遇到了ASP.Net线程的这个问题.我希望每个Web请求都有一个单例对象.我的工作单位实际上需要这个.我想为每个Web请求实例化一个工作单元,以便身份映射在整个请求中有效.这样我就可以使用IoC透明地将我自己的IUnitOfWork注入到我的存储库类中,并且我可以使用相同的实例来查询然后更新我的实体.
由于我使用Unity,我错误地使用了PerThreadLifeTimeManager.我很快意识到ASP.Net线程模型不支持我想要实现的目标.基本上它使用theadpool并回收线程,这意味着每个线程我得到一个UnitOfWork!但是,我想要的是每个Web请求的一个工作单元.
一些谷歌搜索给了我这个伟大的帖子.这正是我想要的; 除了非常容易实现的统一部分.
这是我对PerCallContextLifeTimeManager实现统一的实现:
public class PerCallContextLifeTimeManager : LifetimeManager
{
private const string Key = "SingletonPerCallContext";
public override object GetValue()
{
return CallContext.GetData(Key);
}
public override void SetValue(object newValue)
{
CallContext.SetData(Key, newValue);
}
public override void RemoveValue()
{
}
}
Run Code Online (Sandbox Code Playgroud)
当然,我使用它来使用与此类似的代码注册我的工作单元:
unityContainer
.RegisterType<IUnitOfWork, MyDataContext>(
new PerCallContextLifeTimeManager(),
new InjectionConstructor());
Run Code Online (Sandbox Code Playgroud)
希望能节省一些时间.
我有一个像这样的构造函数的类:
public class Bar
{
public Bar(IFoo foo, IFoo2 foo2, IFoo3 foo3, IFooN fooN, String text)
{
}
}
Run Code Online (Sandbox Code Playgroud)
我想在Unity中注册Bar并为文本提供值:
unity.RegisterType<Bar, Bar>(new InjectionConstructor("123"));
Run Code Online (Sandbox Code Playgroud)
但是我不能这样做,因为Bar没有单个参数构造函数.
有没有办法为文本提供一个值而不指定所有其他参数ResolvedParameter<IFooN>等.我真的不喜欢它,很多代码,每次我更改Bar的构造函数我需要添加另一个ResolvedParameter
unity-container ×10
c# ×6
.net ×1
asp.net ×1
asp.net-mvc ×1
casting ×1
lifetime ×1
mef ×1
reflection ×1
singleton ×1
structuremap ×1
unit-of-work ×1