使用StructureMap的扫描仪注册封闭类型

时间:2012-03-02 17:49:41

标签: dependency-injection structuremap

如何注册封闭类型,以便使用HybridHttpOrThreadLocalScoped生命周期创建泛型实例?

我的课程:

public interface IBaseService
{
}

public interface IAccountService
{
    void Save(Account entry);
    Account GetById(string id);
    List<Account> GetList();
    void Delete(string id);
    bool Exists(string id);
}

public interface IClientService
{
    void Save(Client entry);
    Client GetById(string id);
    List<Client> GetList();
    void Delete(string id);
    bool Exists(string id);
}

public class AccountService : IBaseService, IAccountService
{
    Some code for managing accounts
}

public class ClientService : IBaseService, IClientService
{
    Some code for managing clients
}

依赖性解析器:

    public StructureMapContainer(IContainer container)
    {
        _container = container;

        _container.Configure(x => x.Scan(y =>
        {
            y.AssembliesFromApplicationBaseDirectory();
            y.WithDefaultConventions();
            y.LookForRegistries();
            y.ConnectImplementationsToTypesClosing(typeof(IService<>))
                 .OnAddedPluginTypes(t => t.HybridHttpOrThreadLocalScoped());
        }));

    }

解析程序中用于自动创建IBaseService实例的语法是什么?使用ConnectImplementationsToTypesClosing仅适用于开放式泛型。我甚至需要使用旋转变压器吗?是否有更好的方式来注册类型?

现在,这就是我处理注册的方式:

container.Configure(x =>
        {
            x.For<IClientService>()
                .HybridHttpOrThreadLocalScoped()
                .Use(new ClientService());

            x.For<IEmailAddressService>()
                .HybridHttpOrThreadLocalScoped()
                .Use(new EmailAddressService());

            x.For<IAccountService>()
                .HybridHttpOrThreadLocalScoped()
                .Use(new AccountService());
        });

1 个答案:

答案 0 :(得分:0)

类似的东西:

    Scan(y =>
    {
        y.AssemblyContainingType<IService>();
        y.Assembly(Assembly.GetExecutingAssembly().FullName);
        y.With(new ServiceScanner());
    });

然后你需要海关扫描仪:

/// <summary>
/// Custom scanner to create Service types based on custom convention
/// In this case any type that implements IService and follows the 
/// naming convention of "Name"Service.
/// </summary>
public class ServiceScanner : IRegistrationConvention
{
    public void Process(Type type, StructureMap.Configuration.DSL.Registry registry)
    {
        if (type.BaseType == null) return;

        if (type.GetInterface(typeof(IService).Name) != null)
        {
            var name = type.Name;
            var newtype = type.GetInterface(string.Format("I{0}", name));

            registry
               .For<IService>()
               .AddInstances(y => y.Instance(new ConfiguredInstance(type).Named(name)))
               .HybridHttpOrThreadLocalScoped();

            registry.For(newtype)
                .HybridHttpOrThreadLocalScoped().Use(c => c.GetInstance<IService>(name));
        }
    }
}