所以我完全重构了构造函数注入,现在我有一个类似于这个的bootstrapper类:
var container = new UnityContainer();
container.RegisterType<Type1, Impl1>();
container.RegisterType<Type2, Impl2>();
container.RegisterType<Type3, Impl3>();
container.RegisterType<Type4, Impl4>();
var type4Impl = container.Resolve((typeof)Type4) as Type4;
type4Impl.Run();
Run Code Online (Sandbox Code Playgroud)
我盯着它看了一会儿才意识到Unity对我来说真的没什么特别的.离开ctor sigs,上面的内容可以写成:
Type1 type1Impl = Impl1();
Type2 type2Impl = Impl2();
Type3 type3Impl = Impl3(type1Impl, type2Impl);
Type4 type4Impl = Impl4(type1Impl, type3Impl);
type4Impl.Run();
Run Code Online (Sandbox Code Playgroud)
构造函数注入重构很棒,真正打开了代码的可测试性.但是,我在这里怀疑Unity的用处.我意识到我可能以有限的方式使用框架(即不在任何地方注入容器,使用代码而不是XML进行配置,而不是利用生命周期管理选项),但是我没有看到它在这个示例中实际上是如何帮助的.我已经阅读了不止一条评论,他认为DI最好只用作模式,没有容器.这是一个很好的例子吗?这个解决方案提供了哪些其他好处,我错过了?
我们刚刚将一个项目从prism 2.0升级到prism 4.0,我们遇到Unity问题.显然,Unity 2.0容器XML配置有几处变化,因为我们得到的第一个错误是"无法识别的元素'typeConfig'".这是代码:
// ----------------------- App.config
<configSections>
<section name="runDataParserConfiguration" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<runDataParserConfiguration>
<typeAliases>
<typeAlias alias="IRunDataDispatcher" type="RunDataParser.Interface.IRunDataDispatcher, RunDataParser.Interface" />
<typeAlias alias="IRunDataParser" type="RunDataParser.Interface.IRunDataParser, RunDataParser.Interface" />
<typeAlias alias="IRunDataParserArray" type="RunDataParser.Interface.IRunDataParser[], RunDataParser.Interface" />
<typeAlias alias="Dispatcher" type="RunDataParser.Common.Dispatcher, RunDataParser.Common" />
<typeAlias alias="Parser1" type="RunDataParser.Parser1, RunDataParser" />
<typeAlias alias="Parser2" type="RunDataParser.Parser2, RunDataParser" />
<typeAlias alias="Parser3" type="RunDataParser.Parser3,RunDataParser" />
<typeAlias alias="Parser4" type="RunDataParser.Parser4, RunDataParser" />
<typeAlias alias="Parser5" type="RunDataParser.Parser5, RunDataParser" />
<typeAlias alias="Parser6" type="RunDataParser.Parser6, RunDataParser" />
<typeAlias alias="Parser7" type="RunDataParser.Parser7, RunDataParser" />
<typeAlias alias="Parser8" type="RunDataParser.Parser8, RunDataParser" />
<typeAlias alias="Parser9" type="RunDataParser.Parser9, RunDataParser" /> …Run Code Online (Sandbox Code Playgroud) 好吧,我有一个在基类中定义的依赖属性,我试图在其派生类的构造函数中使用它,但是这不起作用,该属性显示为null.Unity使用container.Resolve()解析实例后解析依赖属性;
我有一个替代方法是将IUnityContainer参数添加到我的MyViewModel类构造函数中,并将ILogger属性设置为我自己,例如:
public MyViewModel(IUnityContainer container)
{
Logger = container.Resolve<ILogger>();
}
Run Code Online (Sandbox Code Playgroud)
编辑: @Wiktor_Zychla的另一个建议是将构造函数注入的参数传递为:
public MyViewModel(ILogger _logger)
{
Logger = _logger;
}
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常,但我必须为我的所有派生的ViewModel做到这一点..
但后来我没有在我的基类中使用带注释的ILogger依赖项.请参阅下面的课程示例.问题是:我有哪些替代方案,或者我做错了什么?
谢谢!
我有一个像这样的ViewModel基类:
public abstract class ViewModelBase
{
[Dependency]
public ILogger Logger { get; set; }
....
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个类推导出:
public class MyViewModel : ViewModelBase
{
public MyViewModel()
{
//I want to use my dependent property in constructor, but doesn't
Logger.Error("PRINT AN ERROR");
}
}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序入口点,我将我的ILogger注册为单例和我的MyViewModel类:
container.RegisterType<ILogger, MyAppLogger>(new ContainerControlledLifetimeManager());
container.RegisterType<MyViewModel>();
Run Code Online (Sandbox Code Playgroud) c# containers dependency-injection inversion-of-control unity-container
我刚刚下载了Unity 3,试试我的新项目.该文档声明此版本允许使用container.RegiserTypes方法按约定注册.但我无法在任何地方找到这种方法.我错过了额外的DLL吗?我使用Nuget将Unity 3添加到我的项目中.
c# dependency-injection inversion-of-control unity-container
我正在构建一个ASP.NET WebApi 2.1应用程序,该应用程序需要与HttpContext.Items等效的每个请求缓存。
我什至不能在IIS托管下使用HttpContext,因为在服务/回购层(HttpContext.Current变为异步工作)时,HttpContext似乎丢失了(使用TPL调用,由于某些接口需要匹配,因此不进行异步/等待)空值)。
我使用的是unity 3.5,无法实现按请求进行正确的注入。尝试了HttpControllerActivator方法:
public class HttpControllerActivator : IHttpControllerActivator
{
private readonly IUnityContainer _container;
private readonly IHttpControllerActivator _activator;
public HttpControllerActivator(IUnityContainer container, IHttpControllerActivator activator)
{
_container = container;
_activator = activator;
}
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
IHttpController controller = _activator.Create(request, controllerDescriptor, controllerType);
_container.RegisterInstance<System.Net.Http.HttpRequestMessage>(request, new HierarchicalLifetimeManager());
return controller;
}
}
Run Code Online (Sandbox Code Playgroud)
但这会将HttpRequestMessage注册在根容器上,而不是在_activator.Create内部由BeginScope()调用创建的子容器上。结果,我在并发负载下得到混合请求实例。
知道如何解决这个问题吗?两天以来我一直在网上搜索,因此没有找到任何真正的解决方案...
我想使用DI与MongoDB的存储库类和接口,但它不起作用.我有这个错误:
MongoRepository`1类型有多个长度为2的构造函数.无法消除歧义.
班级建设者:
public MongoRepository(string connectionString, string collectionName)
{
this.collection = Util<TKey>.GetCollectionFromConnectionString<T>(connectionString, collectionName);
}
public MongoRepository(MongoUrl url, string collectionName)
{
this.collection = Util<TKey>.GetCollectionFromUrl<T>(url, collectionName);
}
Run Code Online (Sandbox Code Playgroud)
Unity配置:
container.RegisterType(typeof(MongoRepository.IRepository<>), typeof(MongoRepository.MongoRepository<>));
Run Code Online (Sandbox Code Playgroud)
如何在Unity中配置DI?谢谢!!
我正在努力提高IoC容器的性能.我们使用的是Unity和SimpleInjector,我们有一个带有这个构造函数的类:
public AuditFacade(
IIocContainer container,
Func<IAuditManager> auditManagerFactory,
Func<ValidatorFactory> validatorCreatorFactory,
IUserContext userContext,
Func<ITenantManager> tenantManagerFactory,
Func<IMonitoringComponent> monitoringComponentFactory)
: base(container, auditManagerFactory, GlobalContext.CurrentTenant,
validatorCreatorFactory, userContext, tenantManagerFactory)
{
_monitoringComponent = new Lazy<IMonitoringComponent>(monitoringComponentFactory);
}
Run Code Online (Sandbox Code Playgroud)
我还有另一个使用此构造函数的类:
public AuditTenantComponent(Func<IAuditTenantRepository> auditTenantRepository)
{
_auditTenantRepository = new Lazy<IAuditTenantRepository>(auditTenantRepository);
}
Run Code Online (Sandbox Code Playgroud)
我看到第二个在大多数时间内在1毫秒内得到解决,而第一个平均需要50-60毫秒.我确定较慢的原因是因为参数,它有更多的参数.但是,如何才能提高速度较慢的性能呢?这是我们Func<T>用作参数的事实吗?如果它导致缓慢,我可以改变什么?
我有一个包含很多类(300+)和BaseClass的程序集,我希望注册一个带接口的泛型类.
如果要解析接口的对象数组,则必须通过{ Name } 注册.我想自动在MainViewModel中有一个对象数组.
有没有办法通过反射自动化这个?有什么建议?
示例(伪):
public class BaseClass
{
public void doFoo();
}
public ClassNumber001 : BaseClass
{
}
public ClassNumber002 : BaseClass
{
}
public interface ISuperman
{
}
public class Superman : ISuperman where T : BaseClass
{
}
public MainViewModel(IEnumerable<ISuperman> lotsofSuperman)
{
}
Run Code Online (Sandbox Code Playgroud)
手工实例:
container.RegisterType<ISuperman, Superman <ClassNumber001>>("ClassNumber001");
container.RegisterType<ISuperman, Superman <ClassNumber002>>("ClassNumber002");
container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>();
Run Code Online (Sandbox Code Playgroud) c# generics ioc-container inversion-of-control unity-container
我需要帮助了解Unity以及IOC的工作原理.
我在UnityContainer中有这个
var container = new UnityContainer();
// Register types
container.RegisterType<IService, Service>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
Run Code Online (Sandbox Code Playgroud)
然后在我的Web API控制器中,我理解IService是由Unity注入的,因为它是一个注册类型.
public class MyController : ApiController
{
private IService _service;
//------- Inject dependency - from Unity 'container.RegisterType'
public MyController(IService service)
{
_service = service;
}
[HttpGet]
public IHttpActionResult Get(int id)
{
var test = _service.GetItemById(id);
return Ok(test);
}
}
Run Code Online (Sandbox Code Playgroud)
我的服务界面
public interface IService
{
Item GetItemById(int id);
}
Run Code Online (Sandbox Code Playgroud)
我的服务实现有自己的构造函数,它接受一个EntityFramework DBContext对象.(EF6)
public class Service : IService
{
private MyDbContext db;
// …Run Code Online (Sandbox Code Playgroud) 我想知道是否有更好的方法来处理此问题。
我已经为我们的项目设置了Unity以进行依赖项注入。该项目本身是使用Web API的ASP.NET应用程序。
我安装了以下软件包。
我看不到在获取数据后立即关闭/处置DBContext的选项。
我的控制器
public class NinjasController : ApiController
{
public Ninja Get(int id)
{
INinjaRepository repository = UnityConfig.Container.Resolve(typeof(INinjaRepository), null) as INinjaRepository;
Ninja ninja = repository.GetNinjaById(id);
repository.CanBeDisposed = true;
repository = null;
UnityConfig.PerRequestLifetimeManager.Dispose();
return ninja;
}
}
Run Code Online (Sandbox Code Playgroud)
UnityConfig
public static class UnityConfig
{
private static Lazy<IUnityContainer> container =
new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer Container => container.Value;
public static PerRequestLifetimeManager PerRequestLifetimeManager;
public static void RegisterTypes(IUnityContainer container) …Run Code Online (Sandbox Code Playgroud) unity-container ×10
c# ×8
.net ×1
asp.net ×1
containers ×1
generics ×1
mongodb ×1
prism ×1
xml ×1