1. 多构造函数
默认情况,DryIOC
期望实现类型仅有一个构造函数。这个构造函数将被使用参数依赖构造注入。
如果一个类有多个构造函数,默认情况下,将会抛出ContainerException
。为了避免发生异常,需要在注册时指定要使用的构造函数。
1.1 使用表达式树指定构造函数
void Main()
{
var c = new Container();
c.Register<IDependency, Dep>();
c.Register<Foo>(made: Made.Of(() => new Foo(Arg.Of<IDependency>())));
Console.WriteLine(c.Resolve<Foo>() is null);
}
public interface IDependency { }
public class Dep : IDependency { }
public class Foo
{
public IDependency Dep { get; }
public Foo(IDependency dep) => Dep = dep;
}
1.2 使用反射指定构造函数
void Main()
{
var c = new Container();
c.Register<IDependency, Dep>();
c.Register<Foo>(made: Made.Of(typeof(Foo).GetConstructor(new[] { typeof(IDependency) })));
Console.WriteLine(c.Resolve<Foo>() is null);
}
public interface IDependency { }
public class Dep : IDependency { }
public class Foo
{
public IDependency Dep { get; }
public Foo(IDependency dep) => Dep = dep;
}
1.3 开放式泛型进行使用反射指定构造函数
void Main()
{
var c = new Container();
c.Register<IDependency<int>, Dep<int>>();
c.Register(typeof(Foo<>), made: Made.Of(typeof(Foo<>).GetConstructors()[0]));
Console.WriteLine(c.Resolve<Foo<int>>() is null);
}
public interface IDependency<T> { }
public class Foo<T>
{
public IDependency<T> Dep { get; }
public Foo(IDependency<T> dep) => Dep = dep;
}
public class Dep<T> : IDependency<T> {}
2. 使用可解析的参数选择构造函数
2.1 使用局部方式
void Main()
{
var c = new Container();
c.Register<A>();
c.Register<C>(made:FactoryMethod.ConstructorWithResolvableArguments);
Console.WriteLine(c.Resolve<C>() is null); //A
}
interface I { }
class A : I { }
class B : I { }
class C
{
public C(A a) { Console.WriteLine("A"); }
public C(B b) { Console.WriteLine("B"); }
}
2.2 使用全局方式
void Main()
{
var c = new Container(rules => rules.With(FactoryMethod.ConstructorWithResolvableArguments));
c.Register<A>();
c.Register<C>();
Console.WriteLine(c.Resolve<C>() is null); //A
}
interface I { }
class A : I { }
class B : I { }
class C
{
public C(A a) { Console.WriteLine("A"); }
public C(B b) { Console.WriteLine("B"); }
}
3. 使用工厂方法替代构造函数
3.1 使用静态工厂方法
void Main()
{
var c = new Container();
c.Register<Repo>();
c.Register<IFoo>(made: Made.Of(() => FooFactory.CreateFoo(Arg.Of<Repo>())));
Console.WriteLine(c.Resolve<IFoo>() is null);
}
public static class FooFactory
{
public static IFoo CreateFoo(Repo repo)
{
var foo = new FooBar();
repo.Add(foo);
return foo;
}
}
public interface IFoo { }
public class FooBar : IFoo { }
public class Repo
{
public void Add(IFoo foo) { }
}
3.2 使用实例工厂方法
void Main()
{
var c = new Container();
c.Register<IFooFactory, FooFactory>(Reuse.Singleton);
c.Register<IDependency, Dep>();
c.Register<Repo>();
c.Register<IFoo>(made: Made.Of(r => ServiceInfo.Of<IFooFactory>(), f => f.CreateFoo(Arg.Of<Repo>())));
Console.WriteLine(c.Resolve<IFoo>() is null);
}
interface IDependency { }
class Dep : IDependency { }
interface IFooFactory { IFoo CreateFoo(Repo repo); }
class FooFactory : IFooFactory
{
public FooFactory(IDependency dep) { }
public IFoo CreateFoo(Repo repo)
{
var foo = new FooBar();
repo.Add(foo);
return foo;
}
}
interface IFoo { }
class FooBar : IFoo { }
class Repo
{
public void Add(IFoo foo) { }
}
4. 属性/字段 工厂方法
void Main()
{
var c = new Container();
c.Register<Repo>();
c.Register<FooFactory>(Reuse.Singleton);
c.Register<IFoo>(made: Made.Of(r => ServiceInfo.Of<FooFactory>(), f => f.Foo));
Console.WriteLine(c.Resolve<IFoo>().Name);
}
public class FooFactory
{
public IFoo Foo { get; private set; }
public FooFactory(Repo repo)
{
Console.WriteLine("FooFactory");
Foo = new Foo(repo);
Foo.Name = "Name:FooFactory";
}
}
public interface IFoo { string Name {get;set;} }
public class Foo : IFoo
{
public string Name {get;set;}
public Foo(Repo repo) { Console.WriteLine("Foo"); this.Name = "Name:Foo";}
}
public class Repo { }
5. 开放式工厂方法
void Main()
{
var container = new Container();
container.Register<Foo>();
container.Register(typeof(Factory<>));
container.Register(typeof(IService<,>), made: Made.Of(typeof(Factory<>).GetSingleMethodOrNull("Create"), ServiceInfo.Of(typeof(Factory<>))));
Console.WriteLine(container.Resolve<IService<Foo, string>>() is null);
}
public interface IService<A, B>
{
void Initialize(A a);
}
public class ServiceImpl<A, B> : IService<A, B>
{
public void Initialize(A a) { }
}
public class Foo { }
[Export]
public class Factory<A>
{
[Export]
public IService<A, B> Create<B>(A a)
{
var service = new ServiceImpl<A, B>();
service.Initialize(a);
return service;
}
}
6. 使用MEF(DryIoc.MefAttributedModel)导出工厂方法
void Main()
{
var container = new Container().WithMefAttributedModel();
container.RegisterExports(typeof(Factory<>), typeof(Foo), typeof(FooDecorator));
Console.WriteLine(container.Resolve<IService<Foo, string>>() is null);
}
public interface IService<A, B>
{
void Initialize(A a);
}
public class ServiceImpl<A, B> : IService<A, B>
{
public void Initialize(A a) { }
}
[Export]
public class Foo { }
[Export, AsDecorator]
public class FooDecorator : Foo
{
public FooDecorator(Foo f) { }
}
[Export]
public class Factory<A>
{
[Export]
public IService<A, B> Create<B>(A a)
{
var service = new ServiceImpl<A, B>();
service.Initialize(a);
return service;
}
}