More control over instantiation of generic types?
I am trying to use StructureMap to register some types that implement a generic interface and are instantiated via a factory.
My code:
public interface IManagerBase<T, TKey> : IDisposable
{
// Get Methods
T GetById(TKey Id);
}
public partial interface IServerHostManager : IManagerBase<ServerHost, int>
{
// ServerHost Specific Get Methods
}
partial class ServerHostManager : ManagerBase<ServerHost, int>, IServerHostManager
{
// Implementation
}
public class ManagerFactory : IManagerFactory
{
public IServerHostManager GetServerHostManager()
{
return new ServerHostManager();
}
}
This works fine:
For<IServerHostManager>().HybridHttpOrThreadLocalScoped()
.Use(new ManagerFactory().GetServerHostManager());
My factory is called and a new instance of IServerHostManager is returned.
Is there any way I can scan for all generic types and have them instantiated via my factory?
This does not work due to ServerHostManager being an internal class:
Scan(x =>
{
x.AssemblyContainingType(typeof(IManagerBase<,>));
x.AddAllTypesOf(typeof(IManagerBase<,>));
x.ConnectImplementationsToTypesClosing(typeof(IManagerBase<,>))
.OnAddedPluginTypes(t => t.HybridHttpOrThreadLocalScoped());
});
What scan command can I use to tell SM to call my factory?
Thank you,
Rick
Followup added on 5/4:
Sorry for the delay in following up.
I’ve got a bunch of manager objects (> 75) that CodeSmith’s nHibernate template has created. They are normally accessed via a factory object. Instead, I’d like to scan for them have them all registered automatically.
This is how I register the objects now:
For<IActivityLogManager>().HybridHttpOrThreadLocalScoped()
.Use(new ManagerFactory().GetActivityLogManager());
For<IAspnetUserManager>().HybridHttpOrThreadLocalScoped()
.Use(new ManagerFactory().GetAspnetUserManager());
Here are the objects
public interface IManagerBase<T, TKey> : IDisposable
{
// Get Methods
T GetById(TKey Id);
}
public partial interface IActivityLogManager : IManagerBase<BusinessObjects.ActivityLog, int>
{
// Get Methods
IList<ActivityLog> GetByActivityTypeId(System.Int32 activityType);
}
public partial class ActivityLogManager : ManagerBase<BusinessObje开发者_如何学Ccts.ActivityLog, int>, IActivityLogManager
{
public IList<ActivityLog> GetByActivityTypeId(System.Int32 activityType)
{
// Code to fetch objects
}
}
public partial interface IAspnetUserManager : IManagerBase<BusinessObjects.AspnetUser, System.Guid>
{
// Get Methods
IList<ActivityLog> GetByActivityTypeId(System.Int32 activityType);
}
public partial class AspnetUserManager : ManagerBase<BusinessObjects.AspnetUser, System.Guid>, IAspnetUserManager
{
public IList<AspnetUser> GetAll()
{
// Code to fetch objects
}
}
My Scan code:
Scan(x =>
{
x.AssemblyContainingType(typeof(IManagerBase<,>));
x.AddAllTypesOf(typeof(IManagerBase<,>));
x.ConnectImplementationsToTypesClosing(typeof(IManagerBase<,>))
.OnAddedPluginTypes(t => t.HybridHttpOrThreadLocalScoped());
});
The Scan code above does not find any objects in the assembly.
I hope this clarifies my scenario.
Thank you,
Rick
This issue can be solved by making the assembly a friend:
[assembly: InternalsVisibleTo("AssemblyB")]
http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx
精彩评论