StructureMap Вопрос - PullRequest
       8

StructureMap Вопрос

0 голосов
/ 02 февраля 2010

Это эквивалент того, что я пытаюсь создать с помощью StructureMap:

new ChangePasswordWithNotificationAndLoggingService(
new ChangePasswordService(
      new ActiveDirectoryRepository(new ActiveDirectoryCredentials()),
      new TokenRepository("")),
new EmailNotificationService(new PasswordChangedNotification(new UserAccount())),
new LoggingService());

Это то, что у меня сейчас есть:

ForRequestedType<IChangePasswordService>()
  .TheDefault.Is.ConstructedBy(() => 
     new ChangePasswordService(DependencyRegistrar.Resolve<IActiveDirectoryRepository>(),
                               DependencyRegistrar.Resolve<ITokenRepository>()))
  .EnrichWith<IChangePasswordService>(x => 
     new ChangePasswordWithNotificationAndLoggingService(x,
                   DependencyRegistrar.Resolve<INotificationService>(),
                   DependencyRegistrar.Resolve<ILoggingService>()));

Мне нужно передать учетную запись пользователя в службу INotificationService ... не могу понять.

Я пробовал это: DependencyRegistrar.With (новый UserAccount {Имя пользователя = "test"});

Не повезло ... UserAccount всегда оказывается нулевым. Мне не нужно делать все это с StructureMap, я открыт для любых предложений.

Вот что у меня сейчас работает:

public static IChangePasswordService ChangePasswordService(UserAccount userAccount)
{
    return new ChangePasswordWithNotificationService(
        new ChangePasswordService(ActiveDirectoryRepository(), TokenRepository()),
        new EmailNotificationService(new PasswordChangedNotification(userAccount)));
}

Ответы [ 2 ]

0 голосов
/ 05 февраля 2010

Почему бы не инкапсулировать создание службы смены паролей в фабрику - тогда фабрика реализуется как фабрика StructureMap, которая использует переданный UserAccount и ObjectFactory для создания экземпляров IIChangePasswordService по мере необходимости?

Я продемонстрировал это ниже:

namespace SMTest
{
class Program
{
    static void Main(string[] args)
    {
        // bootstrapper...
        ObjectFactory.Configure(x => x.AddRegistry(new TestRegistry()));

        // create factory for use later (IoC manages this)...
        var changePasswordServiceFactory = ObjectFactory.GetInstance<IChangePasswordServiceFactory>();

        var daveAccount = new UserAccount("Dave Cox");
        var steveAccount = new UserAccount("Steve Jones");

        var passwordService1 = changePasswordServiceFactory.CreateForUserAccount(daveAccount);
        var passwordService2 = changePasswordServiceFactory.CreateForUserAccount(steveAccount);


    }
}

public class TestRegistry : Registry
{
    public TestRegistry()
    {
        Scan(x =>
                 {
                     x.TheCallingAssembly();
                     x.AssemblyContainingType(typeof(IChangePasswordService));
                     x.AssemblyContainingType(typeof(IActiveDirectoryRepository));
                     x.AssemblyContainingType(typeof(IActiveDirectoryCredentials));
                     x.AssemblyContainingType(typeof(ITokenRepository));
                     x.AssemblyContainingType(typeof(INotification));
                     x.AssemblyContainingType(typeof(INotificationService));
                     x.AssemblyContainingType(typeof(ILoggingService));

                     ForRequestedType<ILoggingService>().TheDefault.Is.OfConcreteType<MyLogger>();

                     ForRequestedType<IActiveDirectoryRepository>().TheDefault.Is.OfConcreteType<MyAdRepository>();
                     ForRequestedType<IActiveDirectoryCredentials>().TheDefault.Is.OfConcreteType<MyAdCredentials>();

                     ForRequestedType<ITokenRepository>().TheDefault.Is.OfConcreteType<MyTokenRepository>();

                     ForRequestedType<IChangePasswordService>().TheDefault.Is.OfConcreteType<ChangePasswordService>();
                     ForRequestedType<IChangePasswordServiceFactory>().CacheBy(InstanceScope.Singleton).TheDefault.Is.OfConcreteType<StructureMapChangePasswordServiceFactory>();

                     ForRequestedType<INotification>().TheDefault.Is.OfConcreteType<MyPasswordChangedNotification>();
                     ForRequestedType<INotificationService>().TheDefault.Is.OfConcreteType<MyEmailNotificationService>();
                 });
    }
}

public interface ILoggingService
{
}

public class MyLogger : ILoggingService
{
}

public class UserAccount
{
    public string Name { get; private set; }

    public UserAccount(string name)
    {
        Name = name;
    }
}

public interface INotification
{
}

public class MyPasswordChangedNotification : INotification
{
    private readonly UserAccount _account;
    private readonly ILoggingService _logger;

    public MyPasswordChangedNotification(UserAccount account, ILoggingService logger)
    {
        _account = account;
        _logger = logger;
    }
}

public interface INotificationService
{
}

public class MyEmailNotificationService : INotificationService
{
    private readonly INotification _notification;
    private readonly ILoggingService _logger;

    public MyEmailNotificationService(INotification notification, ILoggingService logger)
    {
        _notification = notification;
        _logger = logger;
    }
}

public interface ITokenRepository
{
}

public class MyTokenRepository : ITokenRepository
{
}

public interface IActiveDirectoryRepository
{
}

public interface IActiveDirectoryCredentials
{
}

public class MyAdCredentials : IActiveDirectoryCredentials
{
}

public class MyAdRepository : IActiveDirectoryRepository
{
    private readonly IActiveDirectoryCredentials _credentials;

    public MyAdRepository(IActiveDirectoryCredentials credentials)
    {
        _credentials = credentials;
    }
}

public interface IChangePasswordService
{
}

public class ChangePasswordService : IChangePasswordService
{
    private readonly IActiveDirectoryRepository _adRepository;
    private readonly ITokenRepository _tokenRepository;
    private readonly INotificationService _notificationService;

    public ChangePasswordService(IActiveDirectoryRepository adRepository, ITokenRepository tokenRepository, INotificationService notificationService)
    {
        _adRepository = adRepository;
        _tokenRepository = tokenRepository;
        _notificationService = notificationService;
    }
}

public interface IChangePasswordServiceFactory
{
    IChangePasswordService CreateForUserAccount(UserAccount account);
}

public class StructureMapChangePasswordServiceFactory : IChangePasswordServiceFactory
{
    public IChangePasswordService CreateForUserAccount(UserAccount account)
    {
        return ObjectFactory.With(account).GetInstance < IChangePasswordService>();
    }
}
}
0 голосов
/ 02 февраля 2010

Вы пробовали просто использовать AutoWiring ? Это все конкретные классы с простой конструкцией, поэтому StructureMap может определить, что вам нужно.

For<IChangePasswordService>().Use<ChangePasswordService>();

Глядя на вашу конструкцию, я думаю, что эта простая конфигурация может просто сработать.

Редактировать По поводу комментариев.

Вы должны использовать метод With (T instance) , чтобы контейнер создавал ваш IChangePasswordService с использованием заданной userAccount.

var userAccount = new UserAccount("derans"); 
var changePasswordService = container.With(userAccount).GetInstance<IChangePasswordService>();
...