【DryIOC】构造函数与工厂方法

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;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhy29563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值