有人能指导我为WCF服务提供Unity Dependency Injection的好例子吗?任何博客或msdn文章也会有所帮助.
我在Unity中注册了以下类型:
container.RegisterType<IAzureTable<Account>, AzureTable<Account>>();
Run Code Online (Sandbox Code Playgroud)
AzureTable的定义和构造函数如下:
public class AzureTable<T> : AzureTableBase<T>, IInitializer where T : TableServiceEntity
{
public AzureTable() : this(CloudConfiguration.GetStorageAccount()) { }
public AzureTable(CloudStorageAccount account) : this(account, null) { }
public AzureTable(CloudStorageAccount account, string tableName)
: base(account, tableName) { }
Run Code Online (Sandbox Code Playgroud)
我可以在RegisterType行中指定构造函数参数吗?我需要能够传递tableName作为示例.
这是我上一个问题的后续行动.那个问题我想回答了,但我并没有真正明白如何获取构造函数参数.
这似乎是一个愚蠢的问题,因为在我的代码中一切正常,但我用Unity容器以这种方式注册了单例_ambientContainer:
_ambientContainer.RegisterType<Application.StateContext>(new ContainerControlledLifetimeManager());
Run Code Online (Sandbox Code Playgroud)
为了避免使用我的本地字段,我使用:
get {
return ServiceLocator.Current.GetInstance<Application.StateContext>();
}
Run Code Online (Sandbox Code Playgroud)
在我的get属性中获取我的对象的实例.这样我总是得到相同的实例(Application.StateContext仍然是单身)或GetInstance创建一个新的?
改为使用本地_ambientContainer字段会更好吗?
get {
return _ambientContainer.Resolve<Application.StateContext>();
}
Run Code Online (Sandbox Code Playgroud)
谢谢.
c# dependency-injection inversion-of-control unity-container
我试图使用以下通用存储库接口进行DI和构造函数注入:
public interface IRepository<TEntity> : IDisposable where TEntity : class
Run Code Online (Sandbox Code Playgroud)
问题是为了定义接口的实例,我必须提供类似这样的类类型:
private IRepository<Person> _personRepository;
Run Code Online (Sandbox Code Playgroud)
这个问题是如果我使用DI(我使用Unity for IoC框架),那么我必须在构造函数中定义多个实例以获取我需要使用的所有存储库接口,如下所示:
public MyClass(IRepository<Person> personRepository,
IRepository<Orders> ordersRepository,
IRepository<Items> itemsRepository,
IRepository<Locations> locationsRepository)
{
_personRepository = personRepository;
_OrdersRepository = ordersRepository;
_itemsRepository = itemsRepository;
_locationsRepository = locationsRepository;
}
Run Code Online (Sandbox Code Playgroud)
问题:
请帮助我解决这个问题,感谢您的帮助!
我经常读到IOC中的服务定位器是一种反模式.
去年我们将IOC(特别是Ninject)介绍给了我们的工作应用程序.该应用程序是遗留的,它非常大,而且它是碎片化的.有很多方法可以创建类或类链.有些是由Web框架(自定义)创建的,有些是由nHibernate创建的.很多地方都散落在奇怪的地方.
我们如何处理不同的场景,而不是提出一些至少不是ServiceLocatorish的东西,而不是在不同的地方使用不同的内核(像singleton,HttpRequest和thread这样的范围很重要).
编辑我将添加更多细节,以便我们了解当前的SL模式.
事实上,我们不希望多个内核.我们只想要一个(实际上因为SL我们只有一个静态的).这是我们的设置:
1)我们在7-8个不同的项目/组件中有Ninject模块.当我们的应用程序(webapp)启动时,模块通过程序集扫描收集并加载到内核中并放置在服务定位器中.所以这一切都相当昂贵.
2)我们有一个自定义UI框架,结构很开心.想想大约120个选项卡表单,每个表单构建1-10个标签页作为其生命周期的一部分.SL战略性地用于5-6个地方,其覆盖所有这些作为纯分辨率或仅进行后实例化注入属性.
3)UI下的任何内容都不在那些顶级调用中,如果这些类想要使用IOC,他们需要提出自己的策略.有各种不同的小框架,每个框架都是他们自己的小世界.
因此,从我所阅读的内容中做到这一点的理想方法是在需要访问IOC时注入内核......这一切都很好,很好; 我们确实将SL的使用保持在最低限度.
但是我从哪里获得这个内核?我不想在任何地方构建和注册新的.似乎我必须从静态上下文或工厂中获取它,因此我可以确保我正在使用的内核保持其他人正在使用的相同范围的对象,并且还要避免注册所有模块.在那一点上,无论那个东西看起来很像服务定位器吧?
请记住,这个应用程序是巨大的,紧密耦合.我们没有多次花几个月的时间来重构它.对于我们来说,SL似乎是一种很好的方式,可以在我们有时间的地方慢慢地工作.
castle-windsor ninject ioc-container unity-container service-locator
在对其他问题进行一些研究后,我有以下几点:
MyServiceHost:
public class MyServiceHost : ServiceHost
{
public MyServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
foreach (var cd in this.ImplementedContracts.Values)
{
cd.Behaviors.Add(new DependencyInjectionInstanceProvider(container));
}
}
}
Run Code Online (Sandbox Code Playgroud)
DependencyInjectionInstanceProvider:
public class DependencyInjectionInstanceProvider : IInstanceProvider, IContractBehavior
{
private readonly IUnityContainer container;
public DependencyInjectionInstanceProvider(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
#region IInstanceProvider Members
public object GetInstance(InstanceContext instanceContext, Message message)
{
return …Run Code Online (Sandbox Code Playgroud) 这是一个相当直接的装饰器模式场景,其复杂性在于,装饰类型具有一个构造函数参数,该参数取决于它被注入的类型.
我有这样的界面:
interface IThing
{
void Do();
}
Run Code Online (Sandbox Code Playgroud)
这样的实现:
class RealThing : IThing
{
public RealThing(string configuration)
{
... implementation ...
}
public void Do()
{
... implementation ...
}
}
Run Code Online (Sandbox Code Playgroud)
像这样的装饰者:
class DecoratingThing : IThing
{
IThing _innerThing;
public DecoratingThing(IThing thing)
{
_innerThing = thing;
}
public void Do()
{
_innerThing.Do();
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我有一些类型的需要IThing,叫Depender1,Depender2等.
class DependerX()
{
public DependerX(IThing thing)
{
... implementation ...
}
}
Run Code Online (Sandbox Code Playgroud)
我想配置一个IOC容器来解析DependerX它们被注入RealThing装饰的实例DecoratingThing. …
c# dependency-injection ioc-container inversion-of-control unity-container
我正在开发一个Windows服务来做一些定期操作,我可以使用Unity从另一个库中注入我的类吗?
我想在我的服务上使用[Dependency]属性,在Windows服务启动的入口点注册组件.
例:
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
UnityConfig.RegisterComponents();
ServicesToRun = new ServiceBase[]
{
new EventChecker()
};
ServiceBase.Run(ServicesToRun);
}
}
public static class UnityConfig
{
public static void RegisterComponents()
{
UnityContainer container = new UnityContainer();
container.RegisterType<IEventBL, EventBL>();
}
}
public partial class EventChecker : ServiceBase
{
private Logger LOG = LogManager.GetCurrentClassLogger();
[Dependency]
public Lazy<IEventBL> EventBL { get; set; }
protected override void OnStart(string[] args)
{
var events = EventBL.Value.PendingExecution(1);
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,EventBL始终为null,因此不能通过统一的[Dependency]来解决.有没有办法使它工作?
谢谢!
解决方案:
写完答案后我发现了一个可能的解决方案,调用构建容器的方法来创建服务类的工作原理: …
使用Unity创建视图和视图模型
使用Unity作为依赖注入容器与使用MEF类似,并且支持基于属性和基于构造函数的注入.主要区别在于通常不会在运行时隐式发现类型; 相反,他们必须在容器中注册.
通常,您在视图模型上定义接口,以便视图模型的特定具体类型可以与视图分离.例如,视图可以通过构造函数参数定义其对视图模型的依赖性,如此处所示.C#
Run Code Online (Sandbox Code Playgroud)public QuestionnaireView() { InitializeComponent(); } public QuestionnaireView(QuestionnaireViewModel viewModel) : this() { this.DataContext = viewModel; }默认的无参数构造函数是允许视图在设计时工具(如Visual Studio和Expression Blend)中工作所必需的.
或者,您可以在视图上定义只写视图模型属性,如此处所示.Unity将实例化所需的视图模型,并在实例化视图后调用属性setter.C#
Run Code Online (Sandbox Code Playgroud)public QuestionnaireView() { InitializeComponent(); } [Dependency] public QuestionnaireViewModel ViewModel { set { this.DataContext = value; } }视图模型类型已在Unity容器中注册,如此处所示.C#
Run Code Online (Sandbox Code Playgroud)IUnityContainer container; container.RegisterType<QuestionnaireViewModel>();然后可以通过容器实例化视图,如此处所示.C#
Run Code Online (Sandbox Code Playgroud)IUnityContainer container; var view = container.Resolve<QuestionnaireView>();
如果我省略了有关注册ViewModel和实例化View的代码的最后部分,并且只使用将ViewModel挂钩到View的两种方法中的任何一种(使用构造函数或使用属性),那么看起来是ViewModel和View似乎一切都运转良好.那么注册ViewModel并实例化View的代码需要什么?
第一个例子,使用构造函数挂钩View和ViewModel,没有提到所有的Unity,所以Unity实际上在这里使用了吗?
使用基于属性的注射比使用基于construtor的注射有任何优势还是它们完全相同?
文本的第一部分说"*通常,您在视图模型上定义一个接口,以便视图模型的特定具体类型可以与视图分离",然后给出一个示例.然而,这个例子根本没有提到接口.这里发生了什么,我错过了什么吗?
嗨,我一直在努力告诉Unity,如果它有多个实现,我希望它将它们注入不同的类中.这就是我的意思:
比方说,我有一个接口IProductCatalogService和两个实现
ProductCatalog : IProductCatalogService和ProductCatalogService : IProductCatalogService.
我如何告诉Unity,对于类AI,我希望在我的构造函数中传递一个类型的实例,ProductCatalog而对于Class B我想要一个实例ProductCatalogService.
我在ASP.NET Web API项目中使用Unity,并在中设置了解析器GLobalConfiguration.
对于简单的1对1注册,一切正常.
这是我尝试过但它似乎不起作用:
public class DependencyServiceModel
{
public Type From { get; set; }
public Type To { get; set; }
public IEnumerable<Type> ForClasses { get; set; }
}
public void RegisterTypeForSpecificClasses(DependencyServiceModel dependencyService)
{
foreach (var forClass in dependencyService.ForClasses)
{
string uniquename = Guid.NewGuid().ToString();
Container.RegisterType(dependencyService.From,
dependencyService.To, uniquename);
Container.RegisterType(forClass, uniquename,
new InjectionConstructor(
new ResolvedParameter(dependencyService.To)));
}
}
Run Code Online (Sandbox Code Playgroud)
在DependencyServiceModel …