【问题标题】:Using Unity IoC in LINQPad在 LINQPad 中使用 Unity IoC
【发布时间】:2016-07-21 22:48:47
【问题描述】:

我对使用 Unity 很陌生。

我正在尝试在 LINQPad 中测试一段代码。此代码使用依赖于 Log4Net 作为服务的 DBContext。我正在尝试编写示例代码以使用实际的 DBContext,但无法构建它。

我正在尝试的代码如下。如果需要更多信息,请在投反对票之前询问,因为我不确定你需要看多少才能理解我的问题,因为我还在学习 Unity。

void Main()
{
    RegisterObjects();
    var logger = IoCHelper.Resolve<ILogger>();
    //var _logger = new Clark.Logging.MultiLogger();
    var _logger = logger;
    var _ediContext = new EdiContext();
    var transactionId = 1008;
    var limit = 0;

    var temp = new Type210SubscriberProvider(_ediContext)
        .GetAfterNew(transactionId, limit);
    temp.Dump();

    var temp2 = new Type210SubscriberProvider(_ediContext)
        .GetAfter(transactionId, limit);
    temp2.Dump();
}

public void RegisterObjects()
{
    XmlConfigurator.Configure();

    var multiLogger = new MultiLogger();

    multiLogger.Register(new Log4NetLogger());

    IoCHelper.RegisterInstance<ILogger>(multiLogger);
}

如果我试试这个:

void Main()
{
    var _ediContext = new EdiContext();
}

我在 LINQPad 中收到的错误消息是:

依赖项解析失败,type = "Clark.Logging.ILogger",name = "(none)"。 异常发生时:解决时。

异常是:InvalidOperationException - 当前类型 Clark.Logging.ILogger 是一个接口,无法构造。您是否缺少类型映射?

发生异常时,容器为:

正在解决 Clark.Logging.ILogger,(无)

更新:

这里有一些来自 Global.asax.cs 文件的更多细节。我不确定如何将其翻译为 LINQPad。

protected void Application_Start()
{
    // GlobalConfiguration.Configuration is an HttpConfiguration object.
    ConfigureContainer(GlobalConfiguration.Configuration);
    ConfigureServices(GlobalConfiguration.Configuration);

}

private static void ConfigureServices(HttpConfiguration configuration)
{
    configuration.Services.Add(typeof (IExceptionLogger), new UnhandledExceptionLogger(GetLogger()));
    configuration.Services.Replace(typeof (IExceptionHandler), new UnhandledExceptionHandler());
}

private static void ConfigureContainer(HttpConfiguration config)
{
    config.DependencyResolver = new IoCContainer(IoCHelper.Container);

    new LoggingDependencyInitializer().RegisterObjects();

    IoCHelper.RegisterType<IEdiContext>(new InjectionFactory(unityContainer => new EdiContext()));

    IoCHelper.RegisterType<SubscriberController>();
    IoCHelper.RegisterType<ConsumerInformationController>();
    IoCHelper.RegisterType<TransactionTypeController>();
}

private static ILogger GetLogger()
{
    return IoCHelper.Resolve<ILogger>();
}

这是 IoCHelper 类:

public static class IoCHelper
{
    private static UnityContainer _container;

    public static UnityContainer Container
    {
        get { return _container ?? (_container = new UnityContainer()); }
    }

    public static T Resolve<T>()
    {
        return Container.Resolve<T>();
    }

    public static void RegisterType<TFrom, TTo>() where TTo : TFrom
    {
        Container.RegisterType<TFrom, TTo>();
    }

    public static void RegisterInstance(Type type, object instance)
    {
        Container.RegisterInstance(type, instance);
    }

    public static void RegisterType<T>()
    {
        Container.RegisterType<T>();
    }

    public static void RegisterInstance<T>(T instance)
    {
        Container.RegisterInstance(instance);
    }

    public static void RegisterType<T>(InjectionFactory injectionFactory)
    {
        Container.RegisterType<T>(injectionFactory);
    }
}

【问题讨论】:

  • 为什么要在 LinqPad 中尝试这个?您确定它满足所有环境要求,例如XmlConfigurator.Configure(); 吗?
  • 我真的只想测试temptemp2 的代码。基本上只需将上下文传递给我的提供者并查看结果......但要获得上下文,我需要所有这些 IoC 的东西。 EdiContext 要求 Logger 位于内存中的某个位置。

标签: c# entity-framework unity-container


【解决方案1】:

当使用 IOC 容器 时,您需要注册您的类型(例如,将 接口 \ 抽象类 映射到它们的真实类型中)。因为当您希望容器解析一个接口时,它会希望在提供实例之前找到它的映射。

顺便说一句,如果 Unity 没有找到映射,它将尝试构造类型。在您的情况下,它失败了,因为您无法构造 interface

使用 Unity,您可以通过以下方式进行配置:

var section = ConfigurationManager.GetSection(SectionName) as UnityConfigurationSection;
if (section != null)
{
    section.Configure(container);
}

或直接:

container.RegisterType<InterfaceType, ConcreteType>();

因为我在您的示例中看到了此代码行:

IoCHelper.RegisterInstance<ILogger>(multiLogger);

您正在向特定实例注册ILogger。您的IoCHelper 实现一定有问题。请添加更多代码,我将使用特定解决方案编辑我的答案。

【讨论】:

  • 我正在尝试从现有代码中复制。在 WebApi 项目中,我应该在哪里放置/找到它?
  • 我猜是 Global.asax 文件。
  • 请添加 IoCHelper 和 ConfigureContainer 实现。
  • 已添加。我想我想知道的是,如何将 GlobalConfiguration 转换为我可以在 LINQPad 中使用的东西?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多