Регистрация закрытых типов с помощью сканера StructureMap - PullRequest
0 голосов
/ 02 марта 2012

Как зарегистрировать закрытый тип, чтобы экземпляры универсального объекта создавались с использованием жизненного цикла 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 голосов
/ 03 марта 2012

Что-то вроде:

    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));
        }
    }
}
...