Assembly *AssemblySpec::LoadAssembly(LPCWSTR pFilePath) // 传递托管程序集路径
{
CONTRACT(Assembly *)
{
THROWS;
GC_TRIGGERS;
MODE_ANY;
PRECONDITION(CheckPointer(pFilePath));
POSTCONDITION(CheckPointer(RETVAL));
INJECT_FAULT(COMPlusThrowOM(););
}
CONTRACT_END;
AssemblySpec spec; //初始化assemblyspec 类
spec.SetCodeBase(pFilePath); //设置类的托管程序集路径
RETURN spec.LoadAssembly(FILE_LOADED); //设置类的加载方式为 文件加载
}
DomainAssembly *AssemblySpec::LoadDomainAssembly(FileLoadLevel targetLevel, //加载方式,为文件加载,另外三个参数都为空
BOOL fThrowOnFileNotFound,
BOOL fRaisePrebindEvents,
StackCrawlMark *pCallerStackMark)
{
CONTRACT(DomainAssembly *)
{
INSTANCE_CHECK;
THROWS;
GC_TRIGGERS;
MODE_ANY;
POSTCONDITION((!fThrowOnFileNotFound && CheckPointer(RETVAL, NULL_OK))
|| CheckPointer(RETVAL));
INJECT_FAULT(COMPlusThrowOM(););
}
CONTRACT_END;
ETWOnStartup (LoaderCatchCall_V1, LoaderCatchCallEnd_V1); //初始化一些宏定义
AppDomain* pDomain = GetAppDomain(); //获取当前 appdomain 的实例
DomainAssembly *pAssembly = nullptr; //声明并赋值一个 domainassembly
ICLRPrivBinder * pBinder = GetHostBinder(); //获取到 iclrprivbinder 对象
// If no binder was explicitly set, check if parent assembly has a binder.
if (pBinder == nullptr) //如果 pbinder等于零
{
pBinder = GetBindingContextFromParentAssembly(pDomain); //获取到父类和注入的一些方法
}
if (pBinder != nullptr)//如果获取到了
{
ReleaseHolder<ICLRPrivAssembly> pPrivAssembly;
HRESULT hrCachedResult;
if (SUCCEEDED(pBinder->FindAssemblyBySpec(GetAppDomain(), this, &hrCachedResult, &pPrivAssembly)) &&
SUCCEEDED(hrCachedResult))//用pbinder找到appdomain 的pprivassembly
{
pAssembly = pDomain->FindAssembly(pPrivAssembly);//利用找到的pprivassembly,pdomain调用然后赋值给要返回的程序集
}
}
if ((pAssembly == nullptr) && CanUseWithBindingCache()) //如果为空
{
pAssembly = pDomain->FindCachedAssembly(this);//pdomain带上当前类的实例去缓存里面找当前的程序集
}
if (pAssembly)//如果找到
{
pDomain->LoadDomainFile(pAssembly, targetLevel); //以文件方式加载程序集
RETURN pAssembly; //然后返回
}
PEAssemblyHolder pFile(pDomain->BindAssemblySpec(this, fThrowOnFileNotFound, fRaisePrebindEvents, pCallerStackMark));//如果上面所有步骤都不行,实例化一个peassemblyholder,
if (pFile == NULL)
RETURN NULL;
pAssembly = pDomain->LoadDomainAssembly(this, pFile, targetLevel);//利用这个实例化的peassemblyholder和this指针,以及文件加载的方式去获取程序集
RETURN pAssembly; //返回程序集
}