StructureMap Question
This is the equivalent of what I'm trying to create with StructureMap:
new ChangePasswordWithNotificationAndLoggingService(
开发者_JAVA百科new ChangePasswordService(
new ActiveDirectoryRepository(new ActiveDirectoryCredentials()),
new TokenRepository("")),
new EmailNotificationService(new PasswordChangedNotification(new UserAccount())),
new LoggingService());
This is what I have right now:
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>()));
I need to pass the UserAccount to the INotificationService...can't figure it out.
I've tried this: DependencyRegistrar.With(new UserAccount { Username = "test" });
No luck...UserAccount always turns out null. I don't have to do it all with StructureMap, I'm open to any suggestions.
This is what I currently have working:
public static IChangePasswordService ChangePasswordService(UserAccount userAccount)
{
return new ChangePasswordWithNotificationService(
new ChangePasswordService(ActiveDirectoryRepository(), TokenRepository()),
new EmailNotificationService(new PasswordChangedNotification(userAccount)));
}
Have you tried just using AutoWiring? These are all concrete classes with simple construction so StructureMap can figure out what you need.
For<IChangePasswordService>().Use<ChangePasswordService>();
Looking at your construction I think that this simple configuration might just work.
Edit Regarding the comments.
You should use the With(T instance) method to have the container construct your IChangePasswordService using the given userAccount.
var userAccount = new UserAccount("derans");
var changePasswordService = container.With(userAccount).GetInstance<IChangePasswordService>();
Why not encapsulate the creation of the change password service into a factory - the factory is then an implemented as StructureMap factory that use a UserAccount passed in and the 'ObjectFactory' to create instances of the IIChangePasswordService as required?
I have demo'ed it below:
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>();
}
}
}
精彩评论