将Unity DI与控制台应用程序一起使用 [英] Using Unity DI with a Console Application

查看:110
本文介绍了将Unity DI与控制台应用程序一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使Unity与我的控制台应用程序一起使用。..我尝试依赖注入的所有属性仍设置为null。



这是我的代码:



Program.cs

 命名空间.Presentation.Console 
{
类程序
{
静态void Main(string [] args)
{
var mainThread = new MainThread();
}
}
}

MainThread.cs

 命名空间xxxx.Presentation.Console 
{
public class MainThread
{
public IUnitOfWork UnitOfWork {get;组; }

公共IMapper映射器{get;组; }

public MainThread()
{
Mapper.RegisterMappings();
}
}
}

App.config

 <?xml version = 1.0 encoding = utf-8吗? 
< configuration>
< configSections>
< section name = unity type = Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration />
< / configSections>
< startup>
< supportedRuntime版本= v4.0 sku =。NETFramework,Version = v4.5.1 />
< / startup>
< unity xmlns = http://schemas.microsoft.com/practices/2010/unity>
< alias alias = IDataAccess type = UnityFramework.IDataAccess,UnityFramework />
< namespace name = UnityFramework />
< assembly name = UnityFramework />
<容器>
< types>

< type type = IMapper mapTo = xxxx.Core.Parse.ParseMapper />

< / types>
< /容器>
< / unity>
< / configuration>

App.config设置为始终复制



在这种情况下,Mapper在哪里返回为null(我也假定UnitOfWork也是如此)



我还需要做其他事情吗?向app.config添加一些内容?我想念什么吗?



谢谢!



Br,
Inx

解决方案

仅Unity 为通过 Resolve 获得的组件提供依赖关系或解决子依赖性时。必须从容器中手动获取一个或多个根组件。



使用新程序 不是自动提供依赖关系,因为它绕过Unity容器。

 静态类ProgramEntry 
{
static void Main(string [] args)
{
var unity = CreateUnityContainerAndRegisterComponents();
//明确解析一个或多个根组件
var program = unity.Resolve< Program>();
program.Run();
}
}

公共类程序
{
只读Ix _x;

//这些依赖关系将自动解决
//(在这种情况下提供给构造函数)
公共程序(IMapper映射器,IX x)
{
//使用依赖项
mapper.RegisterMappings();

//分配任何相关属性,等等。
_x = x;
}

//在此处进行实际工作
public void Run(){
_x.DoStuff();
}
}

对于大多数任务,我更喜欢基于代码的注册。 / p>


  • 我建议使用属性,尽管它们会起作用 if 遵循上述解决模式。 必须手动解析根对象。



    属性的问题是这些元素在 Unity上添加了依赖项



    构造函数注入(如图所示)是自动/默认。如果首选使用属性注入,请参见在没有属性的Unity中进行Setter /属性注入


  • 我可能会解析一个Factory(或 Func< UoW> )以创建一个UoW和供应适用时,将其沿调用堆栈上下文(即,将其传递给方法)。在一次运行中,该应用程序可能具有许多不同的UoW。在这种情况下,您可能还对创建作用域感兴趣。


  • 我也可能会使用工厂来创建一个预配置的IMapper对象,以解决该问题。之后使用RegisterMappings。



Im trying to get Unity to work with my console application, however.. all the properties that I try to dependency inject are still set to null.

This is my code:

Program.cs

namespace .Presentation.Console
{
    class Program
    {
        static void Main(string[] args)
        {
            var mainThread = new MainThread();
        }
    }
}

MainThread.cs

namespace xxxx.Presentation.Console
{
    public class MainThread
    {
        public IUnitOfWork UnitOfWork { get; set; }

        public IMapper Mapper { get; set; }

        public MainThread()
        {
            Mapper.RegisterMappings();
        }
    }
}

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
  </startup>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <alias alias="IDataAccess" type="UnityFramework.IDataAccess, UnityFramework" />
    <namespace name="UnityFramework" />
    <assembly name="UnityFramework" />
    <container>
      <types>

        <type type="IMapper" mapTo="xxxx.Core.Parse.ParseMapper" />

      </types>
    </container>
  </unity>
</configuration>

App.config is set to Copy Always

Where Mapper is returned as null in this case (and I assume UnitOfWork is as well)

Do I need to do anything else? Add something to the app.config? Am I missing something?

Thanks in advance!

Br, Inx

解决方案

Unity only supplies dependencies for components obtained via Resolve or while resolving sub-dependencies. The "root" component or components must be obtained from the container manually.

Using new Program would not automatically provide the dependencies because it bypasses the Unity container.

static class ProgramEntry
{
    static void Main(string[] args)
    {
        var unity = CreateUnityContainerAndRegisterComponents();
        // Explicitly Resolve the "root" component or components
        var program = unity.Resolve<Program>();
        program.Run();
    }
}

public class Program
{
    readonly Ix _x;

    // These dependencies will be automatically resolved
    // (and in this case supplied to the constructor)
    public Program(IMapper mapper, Ix x)
    {
        // Use dependencies
        mapper.RegisterMappings();

        // Assign any relevant properties, etc.
        _x = x;
    }

    // Do actual work here
    public void Run() {
        _x.DoStuff();
    }
}

I prefer code-based registration for most tasks.

  • I recommend not using attributes, although they 'will work' if following the Resolve pattern above. The "root" objects must be manually resolved.

    The problem with attributes is these add a dependencies on Unity - so much for "inverting"!

    Constructor Injection (as shown) is automatic/default. See Setter / property injection in Unity without attributes if Property Injection is preferred.

  • I would probably resolve a Factory (or Func<UoW>) to create a UoW and supply it down the call-stack context (ie. pass it to methods) when applicable. The application may have many different UoWs during a single run. In this case you may also be interested in creating scopes.

  • I would also probably use a factory to create a pre-configured IMapper object when it is resolved instead of using RegisterMappings afterwards.

这篇关于将Unity DI与控制台应用程序一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆