标签: unity-container

解析同一接口的两个实例

如果我有两个具有相同接口的类,以及一个采用它的两个不同版本的构造函数 - 如何使用 Unity 容器来解决依赖关系?

这是一个简单的测试:

class Dependant
{
    public Dependant(ILog dbLog, ILog fsLog)
    {
        foreach (var i in Enumerable.Range(1, 15))
        {
            if (i%3 == 0)
                dbLog.Log(string.Format("{0} - going to DB", i));
            else
                fsLog.Log(string.Format("{0} - going to FS", i));
        }   
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我想使用容器来解决依赖关系。我试过这个:

static void Main(string[] args)
{
    var container = new UnityContainer();

    container.RegisterType<ILog, DatabaseLogger>();
    container.RegisterType<ILog, FileLogger>();

    var dependant = container.Resolve<Dependant>();
}
Run Code Online (Sandbox Code Playgroud)

但是当使用 FileLogger 的两个实例解析 Dependent 时。我尝试为注册提供名称,以匹配构造函数使用的名称,但这不起作用。

c# dependency-injection unity-container

3
推荐指数
1
解决办法
898
查看次数

Unity无法加载文件或程序集“Microsoft.Practices.ServiceLocation,版本=1.2.0.0”

当我开始我的项目(基于奥尔良项目)时,发现缺少引用引发了一个奇怪的警告:

 [2015-07-26 20:03:06.970 GMT 6 INFO 100000 AssemblyLoader.Client ] User assembly ignored: C:\Users\Gutemberg\Documents\Visual Studio 2015\Projects\PI - Switch (MS)\PI.Switch.Gateway.Host\bin\Debug\Microsoft.Practices.Unity.dll
* An assembly dependency [Microsoft.Practices.ServiceLocation, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Could not load file or assembly 'Microsoft.Practices.ServiceLocation, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.] could not be loaded: 0   
Run Code Online (Sandbox Code Playgroud)

Microsoft.Practices.ServiceLocation 没有出现在 Unity Nuget 包中,我在任何地方都找不到它!这导致我的应用程序出现一些奇怪的运行时行为。

我正在使用 nuget 的最新 Unity。随附的屏幕截图证明了依赖关系 (ILSpy) 以及 VS 上的项目参考 + Nuget 包管理器屏幕。

证据

这个参考真的有必要吗?我怎样才能摆脱它?

谢谢!非常感谢您的帮助。

c# dependency-injection unity-container

3
推荐指数
1
解决办法
7161
查看次数

具有 IOC 的身份框架:“当前类型是一个接口,无法构造”

我必须将所有 IdentityFramework 类和接口移至单独的库,这意味着新的Common.Models.Interfaces接口库只能引用其他接口库(或 .net 库)。这意味着我所有的ApplicationUser参数和变量都变成了IApplicationUser

经过几个小时的更改后,我已经全部构建完毕,但在运行时我收到以下错误:

当前类型 Microsoft.AspNet.Identity.IUserStore`1[Common.Models.Interfaces.Account.IApplicationUser] 是一个接口,无法构造。您是否缺少类型映射?

所以我的问题是:我可能会缺少什么类型映射?

我之前已经使用http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registrationdbcontext中的以下代码解决了问题(特别是使用)InjectionConstructor

container.RegisterType<IApplicationUser, ApplicationUser>();
container.RegisterType<DbContext, ApplicationDbContext>();
container.RegisterType<IdentityDbContext<ApplicationUser>, ApplicationDbContext>();
container.RegisterType<IIdentityMessageService, EmailService>();
container.RegisterType<IApplicationSignInManager, ApplicationSignInManager>();
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new InjectionConstructor(typeof(ApplicationDbContext)));
Run Code Online (Sandbox Code Playgroud)

注意:此处提到的其他错误已删除,因为它具有误导性。看起来我需要额外的映射,但不知道是什么。

应用程序的用户界面和类如下(已修剪),以便您可以发现我出错的地方:

IApplicationUser.cs

public interface IApplicationUser : IUser, IUser<string>
{
     ...
}
Run Code Online (Sandbox Code Playgroud)

应用程序用户.cs

public class ApplicationUser : IdentityUser, IApplicationUser
{
     ...
}
Run Code Online (Sandbox Code Playgroud)

应用程序DbContext.cs

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
Run Code Online (Sandbox Code Playgroud)

显然,不可能包含所有相关代码来重现此问题,因为它运行了 1000 行,并且不需要重现,因此只有 IOC 专家才应申请。:)

第二次尝试:

在获得有用的链接后,@guillaume31我尝试了以下操作:

container.RegisterType(typeof(IUserStore<>), typeof(UserStore<>), new InjectionConstructor(typeof(ApplicationDbContext)));
Run Code Online (Sandbox Code Playgroud)

这可以编译,但我收到一个新错误:

GenericArguments[0], 'Common.Models.Interfaces.Account.IApplicationUser', on …

c# asp.net-mvc entity-framework unity-container asp.net-identity

3
推荐指数
1
解决办法
4226
查看次数

如何在Unity顶部显示ui元素

如何在其他元素之上显示我的 ui 元素?

http://prntscr.com/brjccg您可以看到面板的右侧,但左侧位于地图对象下方。如何解决我想看到它的两面?

这是目前在http://prntscr.com/brjdab上拥有的组件

user-interface unity-container unity-game-engine

3
推荐指数
1
解决办法
2万
查看次数

找不到名称时,统一容器可以解析默认类型吗?

是否可以注册相同的接口两次,其中第一个解析为默认实现,第二个具有名称并解析为另一种类型。

例子:

container.RegisterType(typeof(IMyInterface), typeof(MyDefaultImplementation));
container.RegisterType(typeof(IMyInterface), typeof(MySecondImplementation),"Second Implementations name");
Run Code Online (Sandbox Code Playgroud)

所以,

Resolve<IMyInterface>("non existing name")
Run Code Online (Sandbox Code Playgroud)

应该解决 MyDefaultImplementation。

.net c# unity-container

3
推荐指数
1
解决办法
2034
查看次数

检测到类型 System.Web.IHttpHandler 试图覆盖现有映射

当我将 asp.net mvc 应用程序复制到我们测试服务器的 IIS 文件夹时,我在该应用程序上遇到以下错误。

在本地它工作得很好:

检测到尝试覆盖名称为“”的 System.Web.IHttpHandler 类型(当前映射到 Microsoft.Reporting.WebForms.HttpHandler 类型到 Microsoft.Reporting.WebForms.HttpHandler 类型)的现有映射。

UnityConfig.cs 代码是这样的:

namespace xxx.Relacionamiento.Web.App_Start
{
    /// <summary>
    /// Specifies the Unity configuration for the main container.
    /// </summary>
    public class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        /// <summary>
        /// Gets the configured Unity container.
        /// </summary>
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        /// <summary>Registers the type …
Run Code Online (Sandbox Code Playgroud)

c# asp.net asp.net-mvc unity-container reporting-services

3
推荐指数
1
解决办法
960
查看次数

在 Unity 中使用 IOptions

我有一个从 ASP.Net Core(针对 4.5)和一个 4.5 Web 应用程序引用的类库,我想共享应用程序设置。我在 4.5 端使用 Unity 进行 DI,在 Core 端使用 Core Bootstrapping。在核心方面,我像这样注册了一种我的应用程序设置

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
Run Code Online (Sandbox Code Playgroud)

然后我像这样引用 AppSettings

private readonly AppSettings _appSettings;
public SubmissionRepository(PricingContext dbContext, IMapper mapper, IOptions<AppSettings> appSettings)
{
     _appSettings = appSettings;
}
Run Code Online (Sandbox Code Playgroud)

我想在 4.5 端注册我的服务,我能够在 WebApiConfig.cs 中使用 Unity 进行此操作

container.RegisterType<AppSettings>(new InjectionFactory(o => BuildAppSettings()));
Run Code Online (Sandbox Code Playgroud)

BuildAppSettings 只是使用 ConfigurationManager 填充该类型的实例(不确定这是否是正确的方法)

但是我在运行时遇到异常

无法将“.Core.Integration.Models.AppSettings”类型的对象转换为“Microsoft.Extensions.Options.IOptions`1[Core.Integration.Models.AppSettings]”。

我猜我需要以某种方式将 IOptions 实例放入我的容器中,但不确定如何执行此操作。有没有首选/更好的方法来做到这一点?

.net c# dependency-injection unity-container

3
推荐指数
1
解决办法
1001
查看次数

.NET Unity 拦截使用自定义属性

我想获得这里答案中描述的行为,但通过代码使用配置。代码示例显示创建的自定义属性没有任何与统一相关的内容,并通过配置添加行为。

自定义属性位于同一解决方案中引用的单独程序集中。

问题是它在配置过程中抛出异常:

InvalidOperationException:Microsoft.Practices.Unity.InterceptionExtension.CustomAttributeMatchingRule 类型没有采用参数(LogAttribute、Boolean)的构造函数。

container
    .AddNewExtension<Interception>()
    .Configure<Interception>()
        .AddPolicy("MyLoggingPolicy")
        .AddMatchingRule<CustomAttributeMatchingRule>(
        new InjectionConstructor(typeof(Abstractions.Attributes.LogAttribute), true))
        .AddCallHandler<LoggingHandler>(new ContainerControlledLifetimeManager())
            .Interception
            .Container
        .RegisterType<IFirstInterface>(new InjectionFactory((context) => FirstClassFactoryMethod()))
        .RegisterType<ISecondInterface>(new InjectionFactory((context) => SecondClassFactoryMethod()));

[AttributeUsage(AttributeTargets.Method)]
public class LogAttribute : Attribute { }

public class LoggingHandler : ICallHandler
{
    public int Order { get; set; }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")} Started: {input.MethodBase.Name}");
        var result = getNext()(input, getNext);
        Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")} Completed: {input.MethodBase.Name}");
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新抛出的行:

.AddMatchingRule(
    new CustomAttributeMatchingRule(typeof(Abstractions.Attributes.LogAttribute), true))
Run Code Online (Sandbox Code Playgroud)

防止抛出异常,但 LoggingHandler 不会收到来自具有 …

c# aop unity-container unity-interception

3
推荐指数
1
解决办法
893
查看次数

配置 Unity 解析构造函数参数和接口

我有一个带有两个构造函数参数的 FaxService 类。

public FaxService(string phone, IFaxProvider faxProvider)
Run Code Online (Sandbox Code Playgroud)

Unity 如何配置为发送第一个参数的字符串和第二个参数的 IFaxProvider 实例?我意识到我可以注入另一个提供字符串的服务,但我正在寻找一种不必更改 FaxService 构造函数参数的解决方案。

这就是我到目前为止所拥有的......

class Program
{
    static void Main(string[] args)
    {
        var container = new UnityContainer();

        var phone = "214-123-4567";
        container.RegisterType<IFaxProvider, EFaxProvider>();
        container.RegisterType<IFaxService, FaxService>(phone);

        var fax = container.Resolve<IFaxService>();
    }
}

public interface IFaxService { }

public interface IFaxProvider { }

public class FaxService : IFaxService
{
    public FaxService(string phone, IFaxProvider faxProvider) { }
}

public class EFaxProvider : IFaxProvider { }
Run Code Online (Sandbox Code Playgroud)

但它抛出...

Unity.Exceptions.ResolutionFailedException HResult=0x80131500
Message=依赖关系解析失败,类型=“ConsoleApp3.IFaxService”,名称=“(无)”。while:解决时发生异常。

在此输入图像描述

.net c# inversion-of-control unity-container

3
推荐指数
1
解决办法
4143
查看次数

Unity DI Container RegisterType 方法打破了从 v5.8.x 到 v5.9.x 的变化

我在我的 .NET Core 2.1 项目上使用了Unity DI Container v5.8.4,我需要注册Mediator对象,我正在使用这里建议的配置。

现在我已经更新到v5.9.4并且我有一个关于RegisterType方法参数的错误:

无法从“Unity.Lifetime.LifetimeManager”转换为“Unity.Injection.InjectionMember”

这是我的实际代码:

public static IUnityContainer RegisterMediator(this IUnityContainer container, LifetimeManager lifetimeManager)
{
    return container.RegisterType<IMediator, Mediator>(lifetimeManager)
        .RegisterInstance<ServiceFactory>(type =>
        {
            var enumerableType = type
                .GetInterfaces()
                .Concat(new[] { type })
                .FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));

            return enumerableType != null
                ? container.ResolveAll(enumerableType.GetGenericArguments()[0])
                : container.IsRegistered(type)
                    ? container.Resolve(type)
                    : null;
        });
}
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能更新注册码?

dependency-injection unity-container .net-core mediatr

3
推荐指数
1
解决办法
1256
查看次数