ReadOnlyNameValueCollection (reading from ConfigurationManager.GetSection) - c#

Ok, so.....
<section name="test" type="System.Configuration.NameValueFileSectionHandler" />
<test>
<add key="foo" value="bar" />
</test>
var test = ConfigurationManager.GetSection("test");
So far so good. The debugger shows test contains one key, foo.
But GetSection returns object, so we need a cast:
var type = test.GetType();
// FullName: System.Configuration.ReadOnlyNameValueCollection
// Assembly: System
Ok, this should be simple enough. So....
using System;
var test = ConfigurationManager
.GetSection("test") as ReadOnlyNameValueCollection;
error!
The type or namespace ReadOnlyNameValueCollection does not exist in the namespace System.Configuration. Are you missing an assembly reference?
err... wtf?
A cast to System.Collections.Specialized.NameValueCollection gets the code working, but I don't really understand why the error.
And a search for ReadOnlyNameValueCollection on MSDN shows there is no documentation on this class at all. It doesn't seem to exist. Yet I have an instance of that type in my code.

System.Configuration.ReadOnlyNameValueCollection is an internal class to the System.dll assembly. So you can't refer to it from your code. It derives from System.Collections.Specialized.NameValueCollection, though, so that's why you're able to do that with the cast.

Related

How can I obtain the System.Type of a type in an external shared assembly?

I created a shared assembly MyTypes.dll that contains a public FooBar class type.
I have referenced it in multiple projects and it works as expected.
I have determined its full display name to be: "MyTypes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=624e4a808e6fc010".
I created a new project NewProject and added MyTypes as a reference. I would like to determine the members of FooBar from within NewProject using System.Type.GetType().
Here is what I've written:
// NewProject.cs
using System;
using System.Reflection;
// namespace... class... method...
Type fb;
fb = Type.GetType("MyTypes.FooBar, MyTypes"); // or the full display name
// Exception will be thrown because fb is set to null
MemberInfo[] fbMembers = fb.GetMembers();
However, as noted in the code comments, I cannot provide the correct string format to GetType in order to return a valid Type for the external assembly. Also, this approach will work for anything within the current assembly.
EDIT Turns out the public key token was missing a digit (copy/paste).
The Type.GetType(string) method requires the assembly qualified type name which looks like this:
<Namespace>.<TypeName>, <AssemblyName>, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null
However, if you've referenced the assembly, you should just be able to use typeof(FooBar).GetMembers().

Script# Wrap WebGL?

How would one go about wrapping WebGL in Script#.
I tried to add stuff to the source code but get compile errors I don't understand.
[ScriptIgnoreNamespace]
[ScriptImport]
[ScriptName("webGL")]
public sealed class WebGL
{
[ScriptName("fooGL")]
public void Foo(string test)
{
}
}
Error 1 The base class or interface 'System.FormatException' in
assembly 'mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089' referenced by type
'System.UriFormatException' could not be
resolved c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll Web
Or is there a way better way to add WebGL support as a lib rather then adding it directly to the main source?
EDIT: Looks like that compiler error was coming from VS from auto adding System.dll to the project and it shouldn't be. After removing it now compiles. So now the question is what is the best way to wrap a javaScript API in Script# ??
You should look at the S# source on github for how wrappers are written. They're simply classes tagged with ScriptImport attribute and the internal methods/properties have empty values/bodies.
Look at the source here.

Ninject and XML configuration Binding

i have been searching the internet for any sample or getting start article on how to do binding with Ninject using XML extension but i couldnt find any help ! ,
can any body provide me with a very small sample on how can i do that ?
thanks in advance
I can't find any examples either, but honestly the source code is very small - I would just download (here) and read through the test cases.
The unit test project has some examples, like this:
<module name="basicTest">
<bind name="melee"
service="Ninject.Extensions.Xml.Fakes.IWeapon, Ninject.Extensions.Xml.Test"
to="Ninject.Extensions.Xml.Fakes.Sword, Ninject.Extensions.Xml.Test" />
<bind name="range"
service="Ninject.Extensions.Xml.Fakes.IWeapon, Ninject.Extensions.Xml.Test"
to="Ninject.Extensions.Xml.Fakes.Shuriken, Ninject.Extensions.Xml.Test" />
</module>
It doesn't seem to be very powerful. As someone else pointed out, the point of NInject is to 'free yourself from XML'.
Their only documentation shows what the xml config looks like but they don't give an example of how to load it so here is a simple example which shows both pieces of the puzzle.
Xml Config
This would be in a file called NinjectModules.xml. For it to find the type, I had to give it the assembly qualified name, even though everything was in a single .exe.
<module name="SomeModule">
<bind
service="Birds.IOwl, Birds, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
to="Birds.SlowOwl, Birds, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</module>
Loading Config
IKernel kernel = new StandardKernel();
kernel.Load("c:\path\to\NinjectModules.xml");
IOwl owl = kernel.Get<IOwl>();
owl.Fly();
After lost my saturday and review the Ninject.Extensions.Xml Source, I solve my problem:
(...)
var settings = new NinjectSettings { LoadExtensions = false };
kernel = new StandardKernel(settings, new XmlExtensionModule());
kernel.Load(#"C:\DEV\FSENQUETE\invista.xml");
//kernel.GetModules().Count() --> Ok! Result 34 modules... :)
Got the Solution:
Don't forget to set the Copy to Output of your xml file
Directory property of this file to Copy if newer, so that it can be copied to the
output directory automatically.
for more, see this PDF

Unity application block 2.0 - The given assembly name or codebase was invalid

Interfaces (In the assembly named "Interfaces". In project :- Interfaces)
namespace Interfaces
{
public interface IDoSomeWork1
{
string DoSomeWork1();
}
}
namespace Interfaces
{
public interface IDoSomeWork2
{
string DoSomeWork2();
}
}
Dependencies (In the assembly named "Entities". In project :- Entities)
namespace Entities
{
public class ClassB : IDoSomeWork1
{
public string DoSomeWork1()
{
return this.ToString();
}
}
}
namespace Entities
{
public class ClassC : IDoSomeWork2
{
public string DoSomeWork2()
{
return this.ToString();
}
}
}
Class (In project :- UsingUnity)
public class ClassA
{
[Dependency]
public IDoSomeWork1 DoSomeWork1 { get; set; }
[Dependency]
public IDoSomeWork2 DoSomeWork2 { get; set; }
public void SomeMethodInClassA()
{
Console.WriteLine(DoSomeWork1.DoSomeWork1());
Console.WriteLine(DoSomeWork2.DoSomeWork2());
}
}
App.Config (In a console application project :- ConsoleUsingUnity)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<containers>
<container>
<types>
<type type="Interfaces.IDoSomeWork1, Interfaces"
mapTo="Entities.ClassB, Entities" />
<type type="Interfaces.IDoSomeWork2, Interfaces"
mapTo="Entities.ClassC, Entities" />
</types>
</container>
</containers>
</unity>
</configuration>
The client (In a console application project :- ConsoleUsingUnity)
public class Class1
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
// Load from config file
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(container);
ClassA classA = container.Resolve<ClassA>();
classA.SomeMethodInClassA();
}
}
And when I run the client, I get the following error at section.Configure(container);:-
The given assembly name or codebase
was invalid. (Exception from HRESULT:
0x80131047)
I am not sure If there is anything wrong with the config or the type. Could anyone please point out the mistake here?
In case anyone else ever has the same problem - I was also getting this error but had a slightly different problem. I was trying to load an assembly that clearly existed like the following:
Assembly.Load("C:\\Program Files\\MyProgram\\MyAssembly.dll");
After lots of trial and error I figured out that you aren't supposed to pass the path and you certainly aren't supposed to include .dll extension. The following fixed my issue:
Assembly.Load("MyAssembly");
Hopefully that helps someone else sooner or later!
Before I answer my question, I must state that the code posted above didn't give me any problem (build error etc.). It just gave me the error I stated in my question. The problem with Unity at this point of time is that It does not provide which assembly or a which types in the assembly could not be loaded. This is a requested feature.
In my case It was a missing assembly problem. I didn't reference Entities assembly in to the client application project. It seems that that "Entities" assembly could be resolved only at the run-time (since it didn't give me any compile time error). However, the run-time error was also not useful at all.
I had a look a Fusion Log viewer (It should be in the .NET SDK folder). What a gem of an utility It is. It can log all kind of assembly bindings (all or only failures) and It give a very neat description of which assembly could not load. Very helpful!
So, next time, you get this "The given assembly name or codebase was invalid" error, try Fusion Log Viewer. It wont help you in finding which types couldn't be loaded. However,at least you will be sure all your assemblies are getting loaded correctly.
If you connect up the domain AssemblyResolve event you can get the assembly that has failed to bind.
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
There is a better way now!
Unity has a new version (currently 2.1.505.2) which clearly reports the details and lets you get to the bottom of it immediately.
You can find binaries and source here: http://unity.codeplex.com/releases
I found that the least time consuming method of finding which Type exactly failed to bind is the following:
Go to Sources section of Unity page at codeplex http://unity.codeplex.com/SourceControl/list/changesets
Select a version and download the sources
Build DEBUG version of Unity and Unity.Configuration (if your project uses more of unity assemblies, build them as well)
Remove references to unity from your project and add references to assemblies from step 3
In Visual Studio go to Debug > Exceptions and make sure Common Language Runtime Exceptions has a checkbox in the Thrown column.
Now go crash that thing. Execution will stop in Unitys' TypeResolverImpl.SearchAssemblies method and typeNameOrAlias parameter will hold the answer!
works like this
Dim dllData = System.IO.File.ReadAllBytes(dllFullPath)
Dim asb As System.Reflection.Assembly
asb = System.Reflection.Assembly.Load(dllData)
Dim cls As Object = asb.CreateInstance("namespace.class")
Please make sure, that you have added assembly references of the missing assembly in the project where your web.config file exists.
I was missing this. I already have added those assembly references in the project which was using Unity to resolve the class, but missed to add it in the parent project where configuration file was located. This has resolved my problem.

Registering generic types and services with Castle Windsor IoC

Hello again stackoverflowians,
I thought it was about time that I learnt how to use a DI framework. I've heard a lot of good things about Castle Windsor so I decided to go with that. Now there are PLENTY of tutorials out there on how to use it, however, I cannot find much useful information about what to do when Generics get involved. Here is my issue.
I have a BaseDAO
namespace Utilities.DataAccess
{
public class BaseDAO<T> : IBaseDAO<T>
{
public BaseDAO(IConnectionProvider _connectionProvider)
{
// Stuff
}
}
}
Im a little bit new to generics in this context and I have seen some tutorials which have a 'BaseDAO' with no generic declaration and simply the interface it implements with the generics on it. I have used the above way of doing things on many previous projects (without IoC) and its worked fine for me...anyways, onwards to the App.config !
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="castle"
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"></section>
</configSections>
<castle>
<components>
<component
id="BaseDAO"
service="Utilities.DataAccess.Interfaces.IBaseDAO`1, Utilities.DataAccess"
type="Utilities.DataAccess.BaseDAO`1, Utilities.DataAccess" />
<component
id="NHibernateConnection"
service="Utilities.DataAccess.ConnectionProviders.IConnectionProvider, Finchtils"
type="Utilities.DataAccess.ConnectionProviders.NHibernateConnection" />
<component
id="XMLConnection"
service="Utilities.DataAccess.ConnectionProviders.IConnectionProvider, Finchtils"
type="Utilities.DataAccess.ConnectionProviders.XMLConnection, Utilities" />
</components>
</castle>
</configuration>
Now as some of you may of figured by now, this is a utility library. I intend to use this assembly for each project I create so that I don't have to write the same data access code which remains the same across all solutions. The implications of such of course is that I cannot tell castle exactly what type parameter I will pass to the BaseDAO, in one project it might be a Customer object, another entirely different. I have read on other forums that this is entirely possible as when you request the object from the container you can specify the type then like;
BaseDAO<Customer> baseDao = container.Resolve<BaseDAO<Customer>>();
Although it is against my design efforts, I have tried to use the following notation in the App.config
<component
id="BaseDAO"
service="Utilities.DataAccess.Interfaces.IBaseDAO`1[[Utilities.DataInterface.IEntity]], Finchtills.DataAccess"
type="Utilities.DataAccess.BaseDAO`1[[Utilities.DataInterface.IEntity]], Finchtils.DataAccess" />
However, this has not worked either, in any case I get the following error:
Utilities.Testing.DataAccess.Unit.Testing_BaseDAO (TestFixtureSetUp):
System.Exception : The type name Utilities.DataAccess.BaseDAO`1, Utilities.DataAccess could not be located.
----> System.IO.FileNotFoundException : Could not load file or assembly 'Utilities.DataAccess' or one of its dependencies. The system cannot find the file specified.
Reading this error, I think it could be one of two things:
I am missing something from the config file to do with the generics of the types and services.
I have named something incorrectly I.E an assembly name.
I have treated the assembly name as the project that item is contained within, in other words, at no point have i used <solution name>.<project name>.<item folder>.<item name> but merely started at the project level...I assume that any config option would know what solution it is being called from.
Thank you for any help you may be able to give on this subject.
The assembly name can be found in Visual Studio thus:
In the solution explorer, double-click the properties node
Open the Application tab
Assembly name is near the top right corner
Or, if you're compiling at the command line, you use the /out argument.
Also, you need to specify the assembly for the type arguments (inside the square brackets). So, assuming all your types are in the DataAccess assembly, and that the assembly is called (for brevity's sake) "DataAccess":
<component
id="BaseDAO"
service="Utilities.DataAccess.Interfaces.IBaseDAO`1[[Utilities.DataInterface.IEntity, DataAccess]], DataAccess"
type="Utilities.DataAccess.BaseDAO`1[[Utilities.DataInterface.IEntity, DataAccess]], DataAccess" />
But I agree with other commenters that it's better to do the registrations in code. You don't have to use the verbose type syntax, for one, and you get compiler checking of your types. There are some disadvantages, however: it's harder to tell if you have unused types because the registration call counts as using the type.

Categories