我在测试中配置了一个 ServiceStack AppHostHttpListenerBase,目的是运行如下测试:
public class UserProfileBehaviours : BaseTest<UserProfileService>
{
[Test]
public void Can_access_secure_service()
{
var client = GetClientWithUserPassword();
var result = ((IRestClient)client).Get(new Dto.View.Requests.UserProfileRequest
{
Slug = "user"
});
result.Result.UserAccount.Username.Should().Be("user");
}
}
我的 BaseTest 看起来像:
[TestFixture]
public class BaseTest<T>
{
protected TestAppHostHttpListenerBase<T> AppHost;
private const string ListeningOn = "http://localhost:82/";
private const string UserName = "user";
private const string Password = "p@55word";
protected readonly Container Container;
public BaseTest()
{
Container = new Funq.Container
{
Adapter = new WindsorContainerAdapter()
};
}
[TestFixtureSetUp]
public void OnTestFixtureSetUp()
{
AppHost = new TestAppHostHttpListenerBase<T>();
AppHost.Init();
AppHost.Start(ListeningOn);
}
[TestFixtureTearDown]
public void OnTestFixtureTearDown()
{
AppHost.Dispose();
}
protected IServiceClient GetClient()
{
return new JsonServiceClient(ListeningOn);
}
protected IServiceClient GetClientWithUserPassword()
{
return new JsonServiceClient(ListeningOn)
{
UserName = UserName,
Password = Password
};
}
}
然后是我的 WindsorContainerAdapter:
public static class CastleWindsor
{
public static IWindsorContainer InstallFromAssemblies(this IWindsorContainer container, params string[] assemblyNames)
{
return container.Install(assemblyNames.Select(
x => (IWindsorInstaller)new AssemblyInstaller(Assembly.Load(x), new InstallerFactory())).ToArray());
}
}
public class WindsorContainerAdapter : IContainerAdapter, IDisposable
{
private readonly IWindsorContainer _container;
public WindsorContainerAdapter()
{
_container = new WindsorContainer("Windsor.config");
_container.Register(Component.For<IWindsorContainer>().Instance(_container));
_container.Install(FromAssembly.InThisApplication(), FromAssembly.InDirectory(new ApplicationAssemblyFilter())).InstallFromAssemblies("Web.Api");
_container.Register(Classes.FromAssemblyNamed("Web.Api").BasedOn(typeof(IRepository<>)).LifestyleSingleton());
_container.Register(Component.For<IEmailBuilder>().ImplementedBy<EmailBuilder>().LifeStyle.Singleton);
_container.Register(Component.For<IEmailSender>().ImplementedBy<EmailSender>().LifeStyle.Singleton);
_container.Register(Component.For<IEmailService>().ImplementedBy<EmailService>());
}
public T TryResolve<T>()
{
return !_container.Kernel.HasComponent(typeof(T)) ? default(T) :
Resolve<T>();
}
public T Resolve<T>()
{
return _container.Resolve<T>();
}
public void Dispose()
{
_container.Dispose();
}
}
最后是我的 TestAppHostHttpListener
public class TestAppHostHttpListenerBase<T> : AppHostHttpListenerBase
{
public const string WebHostUrl = "http://localhost:82/";
private InMemoryAuthRepository _userRep;
private const string UserName = "user";
private const string Password = "p@55word";
public const string LoginUrl = "specialLoginPage.html";
public TestAppHostHttpListenerBase()
: base("Validation Tests", typeof(T).Assembly)
{
}
public override void Configure(Container container)
{
var appSettings = new AppSettings();
SetConfig(new EndpointHostConfig { WebHostUrl = WebHostUrl });
Plugins.Add(new AuthFeature(
() =>
new AuthUserSession(),
new IAuthProvider[]
{
new BasicAuthProvider(),
new CredentialsAuthProvider(),
new TwitterAuthProvider(appSettings),
new FacebookAuthProvider(appSettings)
}, "~/" + LoginUrl));
container.Register<ICacheClient>(new MemoryCacheClient());
_userRep = new InMemoryAuthRepository();
container.Register<IUserAuthRepository>(_userRep);
CreateUser(1, UserName, null, Password, new List<string> { "TheRole" }, new List<string> { "ThePermission" });
}
private void CreateUser(int id, string username, string email, string password, List<string> roles = null, List<string> permissions = null)
{
string hash;
string salt;
new SaltedHash().GetHashAndSaltString(password, out hash, out salt);
if (_userRep.GetUserAuthByUserName(username) == null)
{
_userRep.CreateUserAuth(new UserAuth
{
Id = id,
DisplayName = "DisplayName",
Email = email ?? "as@if{0}.com".Fmt(id),
UserName = username,
FirstName = "FirstName",
LastName = "LastName",
PasswordHash = hash,
Salt = salt,
Roles = roles,
Permissions = permissions
}, password);
}
}
}
在配置容器时,我可以看到有一个组件UserAccountRepository
- 如果该组件是UserProfileService
客户端的依赖项,则会收到一个异常,指出无法解决自动装配的依赖项。我不明白的是在哪里AppHostHttpListenerBase
得到它的容器?
我的温莎适配器从未被要求Resolve
存储库的组件。
我怎样才能给AppHostHttpListenerBase
容器以便它可以解决这些依赖关系?还是我需要以另一种方式配置它?