开发者

More control over instantiation of generic types?

开发者 https://www.devze.com 2022-12-28 06:46 出处:网络
I am trying to use StructureMap to register some types that implement a generic interface and are instantiated via a factory.

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

0

精彩评论

暂无评论...
验证码 换一张
取 消