implementing interface not in same dir as class
-
IrvTheSwirv wrote: If you follow the above points, assuming your "usings" are correct too your app will build and assuming the path to the dynamically loading assembly is correct the whole thing will work. (Don't forget to test for a "FileNotFoundException")... I got a question on this issue. Say my EXE looking for the DLL's. They are properly referenced in the project, what if the DLL's (assemblies) are missing physically at runtime. What's the order of searching for this assemblies? ex: search in local directory, if not search in the GAC...._
"FYIFV" Pin made and worn by many Microsoft employees after the company went public. It means, "F*ck You I'm Fully Vested"_
This signature was created by "Code Project Quoter".Here's the answer to that one... from the .NET SDK You can make a dynamic reference to an assembly by providing the calling method with only partial information about the assembly, such as specifying only the assembly name. In this case, only the application directory is searched for the assembly, and no other checking occurs. You make a partial reference using any of the various methods for loading assemblies such as
System.Reflection.Assembly.Load
orAppDomain.Load
. If you want the runtime to check the global assembly cache as well as the application directory for a referenced assembly, you can specify a partial reference using theSystem.Reflection.Assembly.LoadWithPartialName
method. So as usual, it depends! :-D Cheers Shaun -
Here's the answer to that one... from the .NET SDK You can make a dynamic reference to an assembly by providing the calling method with only partial information about the assembly, such as specifying only the assembly name. In this case, only the application directory is searched for the assembly, and no other checking occurs. You make a partial reference using any of the various methods for loading assemblies such as
System.Reflection.Assembly.Load
orAppDomain.Load
. If you want the runtime to check the global assembly cache as well as the application directory for a referenced assembly, you can specify a partial reference using theSystem.Reflection.Assembly.LoadWithPartialName
method. So as usual, it depends! :-D Cheers ShaunThx Shaun. If I want to check for the assemblies in my code, where I have to keep the code? If the assemblies are missing, I want the app to end gracefully instead of crash. BTW, Any code snippet for this? I want to do like this: Retrieve all the assemblies the EXE requires. Find the assemblies in local directory. If they are not there, then show a error and end the app.
Never take a problem to your boss unless you have a solution.
This signature was created by "Code Project Quoter". -
Here's the answer to that one... from the .NET SDK You can make a dynamic reference to an assembly by providing the calling method with only partial information about the assembly, such as specifying only the assembly name. In this case, only the application directory is searched for the assembly, and no other checking occurs. You make a partial reference using any of the various methods for loading assemblies such as
System.Reflection.Assembly.Load
orAppDomain.Load
. If you want the runtime to check the global assembly cache as well as the application directory for a referenced assembly, you can specify a partial reference using theSystem.Reflection.Assembly.LoadWithPartialName
method. So as usual, it depends! :-D Cheers ShaunI already did like this to retrieve the modules needed by app. I was shocked know that it loads 94 DLL's... :omg: :wtf:
ArrayList arrayList = new ArrayList(); foreach (ProcessModule module in Process.GetCurrentProcess().Modules) { arrayList.Add(module); Debug.WriteLine(module.FileName); }
From this 95 DLL's, I want to know about 2 DLL's (assemblies) only. (Shown as Bold in the following list) How to do that? C:\Code Project Quoter\CodeProjectQuoter\bin\Debug\CodeProjectQuoter.exe C:\WINDOWS\System32\ntdll.dll C:\WINDOWS\system32\mscoree.dll C:\WINDOWS\system32\KERNEL32.dll C:\WINDOWS\system32\ADVAPI32.dll C:\WINDOWS\system32\RPCRT4.dll C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\mscorwks.dll C:\WINDOWS\system32\USER32.dll C:\WINDOWS\system32\GDI32.dll C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\MSVCR70.dll C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\fusion.dll C:\WINDOWS\system32\SHELL32.dll C:\WINDOWS\system32\msvcrt.dll C:\WINDOWS\system32\SHLWAPI.dll C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.10.0_x-ww_f7fb5805\comctl32.dll C:\WINDOWS\system32\comctl32.dll c:\windows\microsoft.net\framework\v1.0.3705\mscorlib.dll C:\WINDOWS\system32\ole32.dll C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\diasymreader.dll C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\mscorsn.dll C:\WINDOWS\System32\uxtheme.dll C:\Program Files\Avant Browser\SysHook.dll C:\WINDOWS\system32\oleaut32.dll C:\WINDOWS\System32\SynTPFcs.dll C:\WINDOWS\system32\VERSION.dll C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\MSCORJIT.DLL c:\windows\assembly\gac\system.windows.forms\1.0.3300.0__b77a5c561934e089\system.windows.forms.dll c:\windows\assembly\gac\system\1.0.3300.0__b77a5c561934e089\system.dll c:\windows\assembly\gac\system.drawing\1.0.3300.0__b03f5f7f11d50a3a\system.drawing.dll C:\WINDOWS\System32\netfxperf.dll C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\perfcounter.dll c:\windows\assembly\gac\system.xml\1.0.3300.0__b77a5c561934e089\system.xml.dll C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\CorperfmonExt.dll C:\WINDOWS\System32\PSAPI.dll C:\WINDOWS\System32\aspperf.dll C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\aspnet_isapi.dll C:\WINDOWS\System32\query.dll C:\WINDOWS\System32\infoctrs.dll C:\WINDOWS\System32\INFOADMN.dll C:\WINDOWS\System32\IisRTL.DLL C:\WINDOWS\System32\WS2_32.dll C:\WINDOWS\System32\WS2HELP.dll C:\PROGRA~1\MI6841~1\MSSQL$~1\Binn\sqlctr80.dll C:\PROGRA~1\MI6841~1\MSSQL$~2\Binn\sqlctr80.dll C:\PROGRA~1\MI6 -
Ahhhh! Now I'm with you!! You can't do it that way. You need to put your interfaces in a separate assembly so that they can be shared and accessed by both EXE and DLL without the EXE needing to know anything about the DLL. You can't make the assembly reference the EXE project, that just won't work. Before .NET you could possibly have included another copy of the .cs file that defined the interface in the DLL but because types are best accessed as fully-qualified-names you won't really get away with that. So, to recap. The standard (if indeed, THE correct) way to do what you need to do is to mave your interface definitions from the EXE into a separate dll then reference that project in both the EXE and DLL project. Shaun
Yep that did the trick!! Thanks so much for your help!! It is really appreciated. But I don't understand why the interface needs to be in a separate assembly. I figured that by putting the interface in the same namespace as the user of the interface they would be able to reference each other. What is the concept behind putting the interface in a separate assembly. Or can you give me a brief explanation of why this is the correct architecture. Thanks again for your help.
-
Thx Shaun. If I want to check for the assemblies in my code, where I have to keep the code? If the assemblies are missing, I want the app to end gracefully instead of crash. BTW, Any code snippet for this? I want to do like this: Retrieve all the assemblies the EXE requires. Find the assemblies in local directory. If they are not there, then show a error and end the app.
Never take a problem to your boss unless you have a solution.
This signature was created by "Code Project Quoter".IMHO i think a better approach would be to just handle the FileNotFoundException when you dynamically load the assemblies... but obviously you might know of a good reason to implement what you are describing!
-
Yep that did the trick!! Thanks so much for your help!! It is really appreciated. But I don't understand why the interface needs to be in a separate assembly. I figured that by putting the interface in the same namespace as the user of the interface they would be able to reference each other. What is the concept behind putting the interface in a separate assembly. Or can you give me a brief explanation of why this is the correct architecture. Thanks again for your help.
No Probs... :-D In terms of Interfaces and namespaces I'll try to explain... Just because you put a bunch of types in different assemblies into the same namespaces doesn't mean that those types are merged together into one namespace. When you add a reference to another assembly or project the namespaces of that assembly of project becomes accessible to the exe or dll making the reference. The thing is, if you're typing code and using intellisense the IDE merges the namespaces for you but if you look in object browser I don't think they are. Basically the key to accessing code in another assembly is in the references not the namespaces. (That probably makes no sense at all :wtf: ) As far as the separate dll for Interfaces I'll try to chuck some words down... There are two reasons: one is architectural good practice, the other is a physical considerations. Architectural- Good code design dicatates separating 'interface' from 'implementation' everywhere possible, from 'GUI' and 'Business code', to 'class definitions' and 'implementation'... With interfaces (as in
public interface foo{}
) you might specify a bunch of them for your application and insist that any part of the system that uses other parts of the system do so using interfaces. The advantage of this is that you can make your code modular and extensible without much effort. For example you could have a text editor which has a bunch of import filters which all have to support ITextFilter... in future you might want to add new ones which is no problem so long as the new filters support ITextFilter. Physical- the physical reasons are to do with the old references. If you have a set of assemblies with intefaces and code together then you want to create new code that implements those interfaces too (say on a remote machine for example) you would have to copy all of the dlls with code onto the other machine in order to provide the inteface definition. This is BAD... the best way is to have a small assembly which defines interfaces and have clients and servers reference that. It's also a convenient place to store them too for maintenence. The other limitation in your case was that your interface was defined in your exe which under .NET is a bit of a no-no, as project references only work with .dll type assemblies. Sorry if that was patronising (or wrong :-D) I was kinda in the zone!! Shaun -
IMHO i think a better approach would be to just handle the FileNotFoundException when you dynamically load the assemblies... but obviously you might know of a good reason to implement what you are describing!
IrvTheSwirv wrote: i think a better approach would be to just handle the FileNotFoundException when you dynamically load the assemblies... Thx Shaun. Let me ask the question again.. I don't want to dynamically load the assemblies. When the EXE tries to load the private assemblies (the DLL's EXE requires), if that assembly is not found it will throw the "FileNotFoundException" (Just-In-Time dialog) to the user. Instead of that dialog, I want to catch that exception and display my version of error message and end the application gracefully. Now where should I catch that exception?
Never take a problem to your boss unless you have a solution.
This signature was created by "Code Project Quoter". -
IrvTheSwirv wrote: i think a better approach would be to just handle the FileNotFoundException when you dynamically load the assemblies... Thx Shaun. Let me ask the question again.. I don't want to dynamically load the assemblies. When the EXE tries to load the private assemblies (the DLL's EXE requires), if that assembly is not found it will throw the "FileNotFoundException" (Just-In-Time dialog) to the user. Instead of that dialog, I want to catch that exception and display my version of error message and end the application gracefully. Now where should I catch that exception?
Never take a problem to your boss unless you have a solution.
This signature was created by "Code Project Quoter".Many Many Apologies Kant... I was getting tied up with the other issues in this thread as there seems to be a double stream to it... now that I've re-read I can answer your quezzie!! :-D The exception will be thrown the first time the type in the DLL is requested by the EXE as the runtime will attempt to load the assembly and create the object. What I would do is either find the point in the execution where the types are first loaded and wrap that in the old try catches OR do a quick instantiation of a known class, wrapping it in a try catch for each of the DLLs.. OR create a simple class in each assembly (maybe with a simple static call) and try to call it... OR if none of those are suitable... You could add entries into your App.Config file which lists the dlls you require to exist in your app folder and just do a DirectorySearch... I Dunno... it's tricky!! :omg: :wtf: :omg: :wtf: Shaun
-
Many Many Apologies Kant... I was getting tied up with the other issues in this thread as there seems to be a double stream to it... now that I've re-read I can answer your quezzie!! :-D The exception will be thrown the first time the type in the DLL is requested by the EXE as the runtime will attempt to load the assembly and create the object. What I would do is either find the point in the execution where the types are first loaded and wrap that in the old try catches OR do a quick instantiation of a known class, wrapping it in a try catch for each of the DLLs.. OR create a simple class in each assembly (maybe with a simple static call) and try to call it... OR if none of those are suitable... You could add entries into your App.Config file which lists the dlls you require to exist in your app folder and just do a DirectorySearch... I Dunno... it's tricky!! :omg: :wtf: :omg: :wtf: Shaun
IrvTheSwirv wrote: What I would do is either find the point in the execution where the types are first loaded and wrap that in the old try catches That happens at this point. Application.Run(new Form1()) in Main(). Thanks Shaun, those were excellent suggestions.
Never take a problem to your boss unless you have a solution.
This signature was created by "Code Project Quoter". -
No Probs... :-D In terms of Interfaces and namespaces I'll try to explain... Just because you put a bunch of types in different assemblies into the same namespaces doesn't mean that those types are merged together into one namespace. When you add a reference to another assembly or project the namespaces of that assembly of project becomes accessible to the exe or dll making the reference. The thing is, if you're typing code and using intellisense the IDE merges the namespaces for you but if you look in object browser I don't think they are. Basically the key to accessing code in another assembly is in the references not the namespaces. (That probably makes no sense at all :wtf: ) As far as the separate dll for Interfaces I'll try to chuck some words down... There are two reasons: one is architectural good practice, the other is a physical considerations. Architectural- Good code design dicatates separating 'interface' from 'implementation' everywhere possible, from 'GUI' and 'Business code', to 'class definitions' and 'implementation'... With interfaces (as in
public interface foo{}
) you might specify a bunch of them for your application and insist that any part of the system that uses other parts of the system do so using interfaces. The advantage of this is that you can make your code modular and extensible without much effort. For example you could have a text editor which has a bunch of import filters which all have to support ITextFilter... in future you might want to add new ones which is no problem so long as the new filters support ITextFilter. Physical- the physical reasons are to do with the old references. If you have a set of assemblies with intefaces and code together then you want to create new code that implements those interfaces too (say on a remote machine for example) you would have to copy all of the dlls with code onto the other machine in order to provide the inteface definition. This is BAD... the best way is to have a small assembly which defines interfaces and have clients and servers reference that. It's also a convenient place to store them too for maintenence. The other limitation in your case was that your interface was defined in your exe which under .NET is a bit of a no-no, as project references only work with .dll type assemblies. Sorry if that was patronising (or wrong :-D) I was kinda in the zone!! Shaun