Alguém pode explicar a unidade da Microsoft?

Tenho lido os artigos sobre MSDN sobre Unidade (injeção de Dependência, inversão do controle), mas acho que preciso que seja explicado em termos simples (ou exemplos simples). Estou familiarizado com o padrão MVPC (nós o usamos aqui), mas eu só não posso realmente entender esta coisa de unidade ainda, e eu acho que é o próximo passo em nosso projeto de Aplicação.

Author: Ryan Abbott, 2009-03-04

7 answers

A unidade é apenas um "contentor"do COI. Google StructureMap e experimentá-lo em vez disso. Um pouco mais fácil de engatar, acho eu, quando o COI é novo para ti. Basicamente, se você entender o COI, então você entende que o que está fazendo é inverter o controle para quando um objeto é criado.

Sem Coi:

public class MyClass
{
   IMyService _myService; 

   public MyClass()
   {
      _myService = new SomeConcreteService();    
   }
}

Com recipiente de Coi:

public class MyClass
{
   IMyService _myService; 

   public MyClass(IMyService myService)
   {
      _myService = myService;    
   }
}

Sem o COI, a sua classe que depende do IMyService tem de renovar uma versão concreta do serviço a utilizar. E isso é ruim por uma série de razões (você acoplou sua classe a uma versão concreta específica do IMyService, você não pode testá-lo facilmente, você não pode mudá-lo facilmente, etc.)

Com um Contentor de Coi, você "configura" o contentor para resolver essas dependências por si. Então, com um esquema de injeção baseado em construtores, você apenas passa a interface para a dependência de Serviços de IMyService para o construtor. Quando você criar a MyClass com o seu recipiente, o seu recipiente irá resolver o serviço IMyService dependência para ti.

Usando o StructureMap, a configuração do contentor parece-se com isto:

StructureMapConfiguration.ForRequestedType<MyClass>().TheDefaultIsConcreteType<MyClass>();
StructureMapConfiguration.ForRequestedType<IMyService>().TheDefaultIsConcreteType<SomeConcreteService>();
Então, o que você fez foi dizer ao recipiente, " quando alguém pede o serviço de limpeza, dê-lhes uma cópia do serviço de SomeConcreteService."E você também especificou que quando alguém pede uma classe MyClass, eles recebem uma classe de concreto. É tudo o que um Contentor de Coi faz. Eles podem fazer mais, mas esse é o impulso disso - eles resolvem dependências para você, então você não tem que (e você não tem que usar a palavra-chave "nova" ao longo de seu código).

Passo Final: quando se cria a minha classe, faz-se isto:

var myClass = ObjectFactory.GetInstance<MyClass>();
Espero que isso ajude. Podes mandar-me um e-mail.
 155
Author: Chris Holmes, 2018-06-13 08:23:08
Acabei de ver a injecção de 30 minutos de dependência do COI feita pelo David Hayden e senti que era uma boa explicação com exemplos. Aqui está um excerto das notas do show:

O ecrã mostra vários usos comuns do COI da unidade, tais como:

  • Criar Tipos Que Não Estão No Contentor
  • registar e resolver os tipos de letra
  • registar e resolver os nomes dos tipos
  • Singlets, Lifetimmanagers, and the ContainerControlledLifetimeManager
  • Registar Instâncias Existentes
  • injectar dependências em instâncias existentes
  • a popularizar o aparelho UnityContainer através da aplicação.config / Web.config
  • especificando dependências através da API de injecção em oposição aos atributos de Dependência
  • Usando Recipientes Aninhados (Pais-Filhos)
 35
Author: Kevin Hakanson, 2015-10-15 10:07:16
A unidade é uma biblioteca como muitas outras que lhe permite obter uma instância de um tipo solicitado sem ter que criá-la você mesmo. É verdade.
public interface ICalculator
{
    void Add(int a, int b);
}

public class Calculator : ICalculator
{
    public void Add(int a, int b)
    {
        return a + b;
    }
}

Você usaria uma biblioteca como a unidade para registar a calculadora a ser devolvida quando o tipo de calculadora IC for pedido aka coi (inversão do controlo) (este exemplo é teórico, não é tecnicamente correcto).

IoCLlibrary.Register<ICalculator>.Return<Calculator>();
Então, agora, quando queres um exemplo de um calculador de gelo, é só isso...
Calculator calc = IoCLibrary.Resolve<ICalculator>();

As bibliotecas do COI podem ser configurado para manter um singleton ou criar uma nova instância sempre que resolver um tipo.

Digamos que tem uma aula que depende de um calculador para estar presente..
public class BankingSystem
{
    public BankingSystem(ICalculator calc)
    {
        _calc = calc;
    }

    private ICalculator _calc;
}
E você pode configurar a biblioteca para injectar um objeto no construtor quando ele é criado.

A injecção de DI ou dependência significa Injectar qualquer objecto que possa necessitar.

 30
Author: Chad Moran, 2009-03-03 23:05:14
Este tipo, WilcoxTutorials, dá uma excelente demonstração do contentor da unidade que se dirige aos principiantes.

Parte 1: http://www.youtube.com/watch?v=CWwe9Z0Gyew

Parte 2: http://www.youtube.com/watch?v=PsIbevgzQQE

Em menos de meia hora e você vai entender o básico!

 23
Author: Ben Power, 2013-06-07 21:34:25
A unidade é um coi. O ponto do COI é abstrair a cablagem de dependências entre tipos fora dos próprios tipos. Isto tem algumas vantagens. Em primeiro lugar, é feito centralmente, o que significa que você não tem que alterar um monte de código quando as dependências mudam (o que pode ser o caso para testes de unidade).

Além disso, se a cablagem for feita usando dados de configuração em vez de código, você pode realmente religar as dependências após a implantação e, assim, mudar o comportamento de a aplicação sem alterar o código.

 9
Author: Brian Rasmussen, 2009-03-04 00:33:51

O MSDN tem um guia de desenvolvimento para a injecção de dependências usando o Unity que pode ser útil.

O Guia do programador começa com o básico do que é a injecção de dependência, e continua com exemplos de como usar a unidade para a injecção de dependência. A partir de fevereiro de 2014, o Guia do desenvolvedor cobre Unity 3.0, que foi lançado em abril de 2013.

 4
Author: Simon Tewsi, 2014-02-11 20:24:29

Estou a cobrir a maioria dos exemplos de ASP.NET API 2

Web
public interface IShape
{
    string Name { get; set; }
}

public class NoShape : IShape
{
    public string Name { get; set; } = "I have No Shape";
}

public class Circle : IShape
{
    public string Name { get; set; } = "Circle";
}

public class Rectangle : IShape
{
    public Rectangle(string name)
    {
        this.Name = name;
    }

    public string Name { get; set; } = "Rectangle";
}

In DIAutoV2Controller.cs mecanismo de auto-injecção é utilizado

[RoutePrefix("api/v2/DIAutoExample")]
public class DIAutoV2Controller : ApiController
{
    private string ConstructorInjected;
    private string MethodInjected1;
    private string MethodInjected2;
    private string MethodInjected3;

    [Dependency]
    public IShape NoShape { get; set; }

    [Dependency("Circle")]
    public IShape ShapeCircle { get; set; }

    [Dependency("Rectangle")]
    public IShape ShapeRectangle { get; set; }

    [Dependency("PiValueExample1")]
    public double PiValue { get; set; }

    [InjectionConstructor]
    public DIAutoV2Controller([Dependency("Circle")]IShape shape1, [Dependency("Rectangle")]IShape shape2, IShape shape3)
    {
        this.ConstructorInjected = shape1.Name + " & " + shape2.Name + " & " + shape3.Name;
    }

    [NonAction]
    [InjectionMethod]
    public void Initialize()
    {
        this.MethodInjected1 = "Default Initialize done";
    }

    [NonAction]
    [InjectionMethod]
    public void Initialize2([Dependency("Circle")]IShape shape1)
    {
        this.MethodInjected2 = shape1.Name;
    }

    [NonAction]
    [InjectionMethod]
    public void Initialize3(IShape shape1)
    {
        this.MethodInjected3 = shape1.Name;
    }

    [HttpGet]
    [Route("constructorinjection")]
    public string constructorinjection()
    {
        return "Constructor Injected: " + this.ConstructorInjected;
    }

    [HttpGet]
    [Route("GetNoShape")]
    public string GetNoShape()
    {
        return "Property Injected: " + this.NoShape.Name;
    }

    [HttpGet]
    [Route("GetShapeCircle")]
    public string GetShapeCircle()
    {
        return "Property Injected: " + this.ShapeCircle.Name;
    }

    [HttpGet]
    [Route("GetShapeRectangle")]
    public string GetShapeRectangle()
    {
        return "Property Injected: " + this.ShapeRectangle.Name;
    }

    [HttpGet]
    [Route("GetPiValue")]
    public string GetPiValue()
    {
        return "Property Injected: " + this.PiValue;
    }

    [HttpGet]
    [Route("MethodInjected1")]
    public string InjectionMethod1()
    {
        return "Method Injected: " + this.MethodInjected1;
    }

    [HttpGet]
    [Route("MethodInjected2")]
    public string InjectionMethod2()
    {
        return "Method Injected: " + this.MethodInjected2;
    }

    [HttpGet]
    [Route("MethodInjected3")]
    public string InjectionMethod3()
    {
        return "Method Injected: " + this.MethodInjected3;
    }
}

In DIV2Controller.cs tudo será injectado a partir da classe de resolução de configuração de dependências

[RoutePrefix("api/v2/DIExample")]
public class DIV2Controller : ApiController
{
    private string ConstructorInjected;
    private string MethodInjected1;
    private string MethodInjected2;
    public string MyPropertyName { get; set; }
    public double PiValue1 { get; set; }
    public double PiValue2 { get; set; }
    public IShape Shape { get; set; }

    // MethodInjected
    [NonAction]
    public void Initialize()
    {
        this.MethodInjected1 = "Default Initialize done";
    }

    // MethodInjected
    [NonAction]
    public void Initialize2(string myproperty1, IShape shape1, string myproperty2, IShape shape2)
    {
        this.MethodInjected2 = myproperty1 + " & " + shape1.Name + " & " + myproperty2 + " & " + shape2.Name;
    }

    public DIV2Controller(string myproperty1, IShape shape1, string myproperty2, IShape shape2)
    {
        this.ConstructorInjected = myproperty1 + " & " + shape1.Name + " & " + myproperty2 + " & " + shape2.Name;
    }

    [HttpGet]
    [Route("constructorinjection")]
    public string constructorinjection()
    {
        return "Constructor Injected: " + this.ConstructorInjected;
    }

    [HttpGet]
    [Route("PropertyInjected")]
    public string InjectionProperty()
    {
        return "Property Injected: " + this.MyPropertyName;
    }

    [HttpGet]
    [Route("GetPiValue1")]
    public string GetPiValue1()
    {
        return "Property Injected: " + this.PiValue1;
    }

    [HttpGet]
    [Route("GetPiValue2")]
    public string GetPiValue2()
    {
        return "Property Injected: " + this.PiValue2;
    }

    [HttpGet]
    [Route("GetShape")]
    public string GetShape()
    {
        return "Property Injected: " + this.Shape.Name;
    }

    [HttpGet]
    [Route("MethodInjected1")]
    public string InjectionMethod1()
    {
        return "Method Injected: " + this.MethodInjected1;
    }

    [HttpGet]
    [Route("MethodInjected2")]
    public string InjectionMethod2()
    {
        return "Method Injected: " + this.MethodInjected2;
    }
}

Configurar o resolvedor de dependências

public static void Register(HttpConfiguration config)
{
    var container = new UnityContainer();
    RegisterInterfaces(container);
    config.DependencyResolver = new UnityResolver(container);

    // Other Web API configuration not shown.
}

private static void RegisterInterfaces(UnityContainer container)
{
    var dbContext = new SchoolDbContext();
    // Registration with constructor injection
    container.RegisterType<IStudentRepository, StudentRepository>(new InjectionConstructor(dbContext));
    container.RegisterType<ICourseRepository, CourseRepository>(new InjectionConstructor(dbContext));

    // Set constant/default value of Pi = 3.141 
    container.RegisterInstance<double>("PiValueExample1", 3.141);
    container.RegisterInstance<double>("PiValueExample2", 3.14);

    // without a name
    container.RegisterInstance<IShape>(new NoShape());

    // with circle name
    container.RegisterType<IShape, Circle>("Circle", new InjectionProperty("Name", "I am Circle"));

    // with rectangle name
    container.RegisterType<IShape, Rectangle>("Rectangle", new InjectionConstructor("I am Rectangle"));

    // Complex type like Constructor, Property and method injection
    container.RegisterType<DIV2Controller, DIV2Controller>(
        new InjectionConstructor("Constructor Value1", container.Resolve<IShape>("Circle"), "Constructor Value2", container.Resolve<IShape>()),
        new InjectionMethod("Initialize"),
        new InjectionMethod("Initialize2", "Value1", container.Resolve<IShape>("Circle"), "Value2", container.Resolve<IShape>()),
        new InjectionProperty("MyPropertyName", "Property Value"),
        new InjectionProperty("PiValue1", container.Resolve<double>("PiValueExample1")),
        new InjectionProperty("Shape", container.Resolve<IShape>("Rectangle")),
        new InjectionProperty("PiValue2", container.Resolve<double>("PiValueExample2")));
}
 1
Author: Narottam Goyal, 2018-08-21 08:06:56