按名称AutoFac创建一组实例

时间:2016-10-26 13:06:10

标签: c# autofac

假设我有这个课程:

public class ProcessObject : IProcessObject
{
    public string Name { get; set; }
    public ProcessObject(String Name)
    {
        this.Name = Name;
    }
}
public interface IProcessObject
{
    string Name { get; set; }
}

将AutoFac用作IoC-Container我需要能够通过属性Name来检索此类的唯一实例。

如果已经创建了某个名称的过程对象,我想返回该特定实例。

“示例使用代码”

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<ProcessObject>();
builder.RegisterType<ProcessObject>().As<IProcessObject>().;
Container = builder.Build();
var obj1 = Container.Resolve<IProcessObject>(new NamedParameter("Name", "UniqueObjectByName1"));//Does not exist, create new instance
var obj2 = Container.Resolve<IProcessObject>(new NamedParameter("Name", "UniqueObjectByName1"));//An instance with this name exists, return that instance
var obj3 = Container.Resolve<IProcessObject>(new NamedParameter("Name", "UniqueObjectByName2"));//Does not exist, create new instance
Debug.WriteLine(obj1.Equals(obj2));//this is currently returning False, I would like it to be true
Debug.WriteLine(obj1.Equals(obj3));

在我目前的代码中,我通过在ProcessObject类和单例列表中使用静态方法来保持这个原则,以便跟踪我的所有ProcessObjects。

public static GetInstance(string Name)
{
    if (ProcessObjects.GetInstanceByName(Name) == null)
    {
        return new ProcessObject(Name);
    }
    else return ProcessObjects.GetInstanceByName(Name);
}

我是否仍然需要这个,或者AutoFac是否提供了通过属性值返回唯一实例的解决方案?

1 个答案:

答案 0 :(得分:1)

Autofac不允许您动态命名对象或添加元数据,因此您仍需要使用工厂方法按名称缓存实例。

但是,您可以将该工厂绑定到Autofac,以便它似乎就像它按名称缓存一样:

// Let's say your factory is like this, where the cache
// is stored in the instance, like a hash table. Adjust
// your code as necessary.
builder.RegisterType<MyCachingFactory>()
  .As<IFactory>()
  .SingleInstance();

// Register a lambda that looks at the inbound set
// of parameters and uses the registered factory
// to resolve.
builder.Register((c, p) =>
{
  var name = p.Named<string>("Name");
  var factory = c.Resolve<IFactory>();
  return factory.GetInstanceByName(name);
}).As<IProcessObject>();

这样做,你应该能够做你想要的事情:

container.Resolve<IProcessObject>(new NamedParameter("Name", "a"));