It appears this is the case. If I am marking a generic as a closed type, I am stating my intention to use a Type and not an Instance of a Type. I am getting an error as Unity is trying to resolve the closing type in the ExternalLinkingRepository class below. The error states that Unity can not reconcile the constructor as there is more than 1 with the same number of parameters (2). I have looked at constructor injectors (and indeed need one for the connection string, but this is not the issue) Any ideas as to why Unity tries to instantiate the closing Type?
This is a snippet of the registration with my container and code. What am I missing or misunderstanding:
// Bootstrapping location...
.RegisterType<ICampaignRepository, ExternalLinkingRepository>()
// Concrete Repository -- CampaignDataContext is the cause of issue
public class ExternalLinkingRepository : RepositoryBase<CampaignDataContext>, ICampaignRepository
{
// blah
}
//Base class
public abstract class RepositoryBase<T> where T : DataContext, IDisposable
{
protected T _dataContext;
public RepositoryBase(String connectionString)
{
if (_dataContext == null)
{
_dataContext = (T)new DataContext(connectionString);
}
}
public void Dispose()
{
if (_dataContext != null)
{
GC.SuppressFinalize(_dataContext);
_dataContext.Connection.Close();
}
}
}
EDIT More detailed code listing and error messages for anyaysis *Container Config*
IUnityContainer container = new UnityContainer();
// *****NB**** The code below throws an exception - this is a know bug with Unity
// If you have the exception manager set to break on "thrown" exceptions (as opposed to just userhandled exceptions) you will be stopped here.
// However, the exception IS handled within the Unity framework and execution of the application can continue safely. The next release of Unity will fix this.
// Remove this message when vNext Unity is used.
container.RegisterType<IBusinessManager, KnowledgeKubeBusinessManager>()
.RegisterType<IDataManager, KnowledgeKubeDataManager>()
// In this instance, specific concrete types are registered for the interfaces specified in the constructor of the UserManagerFactory
.RegisterType<IUserManagerFactory, UserManagerFactory>(new InjectionConstructor(new ResolvedParameter(typeof(FormsAuthenticatedUserManager)), new ResolvedParameter(typeof(WindowsAuthenticatedUserManager))))
.RegisterType<IApplicationConfigurationSettings, ApplicastionConfigurationSettings>()
.RegisterType<IKnowledgeKubeSessionProvider, KnowledgeKubeManagerSessionProvider>()
.RegisterType<IQuestionnaireQueryArgs, AnsweredKnowledgeQuestionnaireQueryArgs>()
.RegisterType<ICampaignBusinessManager, CampaignBusinessManager>()
.RegisterType<ICampaignRepository, ExternalLinkingRepository>(new InjectionConstructor(ConnectionString))
// Add Interception on KnowledgeKubeDataManager using the VirtualMethodInterceptor (Much Faster than the TransparentProxyInterceptor)
.AddNewExtension<Interception>().Configure<Interception>().SetDefaultInterceptorFor<KnowledgeKubeDataManager>(new VirtualMethodInterceptor())
.Container.AddNewExtension<Interception>().Configure<Interception>().SetDefaultInterceptorFor<WindowsAuthenticatedUserManager>(new VirtualMethodInterceptor());
ExternalLinkingRepository config
/// <summary>
/// TODO: Some refactoring going on here from Campaign to external data linking.
/// </summary>
public class ExternalLinkingRepository : RepositoryBase<CampaignDataContext>, ICampaignRepository
{
public ExternalLinkingRepository(String connectionString) : base(connectionString) { }
public void GetKnowledgeAreaIDs(String externalURLID, String username, out Guid userID, out Int32 knowledgeGroupID, out Int32 knowledgeQuestionnaireID)
{
knowledgeGroupID = 0;
knowledgeQuestionnaireID = 0;
userID = Guid.Empty;
try
{
int productIdx = 0;
foreach (var result in _dataContext.usp_GetKnowledgeAreaIDSByExternalURLID(externalURLID,username))
{
// blah
Error Message
Server Error in '/WhiteBox' Application. The type CampaignDataContext has multiple constructors of length 2. Unable to disambiguate. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The type CampaignDataContext has multiple constructors of length 2. Unable to disambiguate.
Source Error:
Line 115: _container = container; Line 116:
Line 117: container.BuildUp(this as T); Line 118:
Line 119: }Source File: C:\Development\Acropolis\Development\KnowledgeKube_1.0.0\Acropolis Suite\WhiteBox\WhiteBox\Web\WhiteBoxBasePage.cs Line: 117
Stack Trace:
[InvalidOperationException: The type CampaignDataContext has multiple constructors of >length 2. Unable to disambiguate.] Microsoft.Practices.ObjectBuilder2.ConstructorSelectorPolicyBase`1.FindLongestConstructor(>Type typeToConstruct) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder>\Strategies\BuildPlan\Creation\ConstructorSelectorPolicyBase.cs:113
Unity does not create instances of objects during the setup phase. But when you register a mapping Unity tries to identify the constructor to use when creating an instance. By default Unity will pick the constructor that takes the most parameters (most greedy constructor). If there is more than one constructor that takes the maximum number of parameters (I'm not sure but from your description it sounds like there are two ctors that take 1 parameter?) Unity cannot decide which constructor to use and thus throws an exception. To resolve this issue you can either remove one of the constructors or tell Unity explicitely which constructor to use
or if you have a ctor that takes arguments you want to be resolved by Unity you can specify them by their type