Alguém pode explicar a unidade da Microsoft?
7 answers
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.
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)
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.
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!
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.
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.
Estou a cobrir a maioria dos exemplos de ASP.NET API 2
Webpublic 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")));
}