I'm attempting to create a T4 template that generates source code for calling stored procedures that are contained in another project in my solution. I am able to successfully enumerate the .sql files in the solution, add them to a TSqlModel, and use that model to retrieve the list of stored procedures as TSqlObject instances. Now, I need to enumerate the parameters for each stored procedure, and this is where I'm getting hung up.
When I debug my template, I can see that the TSqlObject instances have a ContextObject property, and this property contains, among other things, the list of parameters that I need to generate my code. When I attempt to access this property from my template, however, the compiler complains that the property doesn't exist:
Error 1 Compiling transformation: 'Microsoft.SqlServer.Dac.Model.TSqlObject' does not contain a definition for 'ContextObject' and no extension method 'ContextObject' accepting a first argument of type 'Microsoft.SqlServer.Dac.Model.TSqlObject' could be found (are you missing a using directive or an assembly reference?) d:\Code\cs\test_sproccodegen\CallingProject\sproc_template.tt 34 111 CallingProject
I can definitely access this ContextObject property from the Immediate window while debugging, but it is not available at compile time.
What am I doing wrong?
The property isn't listed in the API, which probably means it's internal or private. Only public and protected accessible members are included in the docs.
Checking it out in JustDecompile, you can see it is, in fact, internal.
That's an internal method as mentioned by Will in the question comments. You should use the public APIs instead. The following documenation should help you get started:
Model API Reference
Public Model Tutorial
Dac samples project. There aren't any T4 template examples but it has a lot of examples of querying and even manipulating the model. You just need to put that in T4 template form.
Related
I'm currently studying UFT. I encountered this: I have one object, which is a textbox field on my repository. I used that specific object twice on my script. The warning then occurs. "The object was not found using the test object description. Check the object's properties." May I know what to do so that warning will no longer occur?
This warning means that UFT was not able to identify the object using the primary description it stored and that a fallback method called Smart Identification was used.
This means that the identification properties that you're currently using (either Object Repository or descriptive programming) are out of sync with your web application and it's recommended that you update the description (perhaps by adding regular expressions).
The report should list which properties where used by Smart Identification and which were skipped), this may be a good starting point to choosing your description.
I'm writing an implementation for a mailing service and I'm having trouble with the code that VisualStudio autogenerates from the wsdl file. The API contains several versions of the same objects. The objects are defined in separate xsd files corresponding to a particular version:
Although each xsd file defines a specific namespace, the complex element names are the exact same in all xsd files:
This causes VisualStudio to assign arbitrary names to the classes representing the complex names to retain uniqueness:
If you look at the xsd files, OpenMailingGroup_13B returns an OpenMailingGroupResponse and OpenMailingGroup_15A also returns an OpenMailingGroupResponse, and IMHO that's ok from a definition point of view because they are defined in separate xsd files each having its own separate namespace. However, when VisualStudio generates the proxy classes, it names the return type of OpenMailingGroup_13B as OpenMailingGroupResponse2 and the return type of OpenMailingGroup_15A as OpenMailingGroupResponse4.
This becomes an issue when you update the web service reference and new versions are added and removed (e.g. a new OpenMailingGroup_17X now exists). The problem is that VisualStudio would now use a different naming for the OpenMailingGroupResponse. What was OpenMailingGroupResponse4 for OpenMailingGroup_15A could not be OpenMailingGroupResponse9. And that breaks our code.
We thought of a few possible solutions:
Writing adapter classes - but there are literally hundreds of classes and that would be too painful.
Using var in the variable definition in order not to hardcode the type, but there's lots of nesting involved (e.g. a complex type has another complex type which has another complex type, etc.).
Not update the wsdl...
So, my question is: can I tell VisualStudio to split the generated code into multiple .NET namespaces, each corresponding to its xsd file? Maybe a general question is: is there anything I can do about this?
Thanks in advance,
Tiberiu
I have been trying to use BLToolkit to activate an Oracle stored procedure which takes a User Defined Type as an argument as an output parameter and changes it.
I have managed to do this on a primitive type, and and also by manually calling SetSpCommamd however I would like to use the abstract class generation method but can't seem to get it to work.
I'm pretty sure the code I wrote is correct (works for the primitive). When debugging I found the SetSpCommamd called by the generated code gets wierd parameters instead of the ones I provided as opposed to when I call the method manually (the it gets the exact parameters I'd like). I wish I could see the code generated by the reflection emit to see what's wrong there.
Can anyone please help me figure out why this is not working?
Found the problem (Potentially a bug in BLToolkit).
BLToolkit does not pass the UDT Class as is to the procedure (instead it tries to flatten it or something and pass the insides of the object). I Changed the object to a Struct instead of a Class and that fixed it.
Later on I also changed it back to class and made a patch in the 'IsScaler()' method in BLToolkits code.
I will report this as a Bug I hope they fix it.
I'm having some serious troubles getting a Windows Phone 7.5 class library to load into the WP Unit Test Framework. It internally calls GetExportedTypes() on my assembly which throws a ReflectionTypeLoadException that doesn't contain any details. Its message is "ReflectionTypeLoadException" and its LoaderExceptions is null ("Could not evaluate expression"). The assembly is not using any 3rd party assemblies. If I create a separate WP7 app and do the same thing, I get the same results. I'm a very experienced Reflection user, but the lack of any detailed errors has brought my research to a complete halt. Just for completeness, it's the Windows Phone version of Fluent Assertions.
What about the Types array on the exception? Does it contain values? If so, does it also contain nulls? If so, you can find out which classes failed to load: You know all classes in the assembly and you know which classes loaded correctly. Those that are missing are the classes that couldn't be loaded. Maybe this info gives some clues.
This answer is based on the documentation, especially these bits:
From the Remarks of the LoaderExceptions property:
The LoaderExceptions property retrieves an array of type Exception that is parallel to the Types array. This array will contain null values whenever reflection cannot load a class.
And from the documentation of the Types property:
An array of type Type containing the classes that were defined in the module and loaded. This array can contain some null values.
I've found it! #GeertvanHorrik pointed me at a blog post he recently wrote. I was using an covariant interface (using the out parameter) which the runtime (!) doesn't support. Why the compiler does not protect me from that is a big mystery (and a huge disappointment) to me
I'm throwing this out in case someone has encountered this before.
When creating DesignData for use within the WPF designer, I get one of two errors:
Object does not match target type.
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object
target)
(SNIP)
at Microsoft.Expression.DesignModel.InstanceBuilders.ClrObjectInstanceBuilder. UpdateProperty(IInstanceBuilderContext
context, ViewNode viewNode, IProperty
propertyKey, DocumentNode valueNode)
The other one is a little more informative:
The value "_.di0.MyProjectLol.MyType"
is not of type "MyProjectLol.MyType"
and cannot be used in this generic
collection.
at
System.ThrowHelper.ThrowWrongValueTypeArgumentException(Object
value, Type targetType)
(SNIP)
at Microsoft.Expression.DesignModel.InstanceBuilders.ClrObjectInstanceBuilder.
InstantiateChildren(IInstanceBuilderContext
context, ViewNode viewNode,
DocumentCompositeNode compositeNode,
Boolean isNewInstance)
When debugging, I can see that there is a dynamic assembly that is loaded with proxy-ish types that look like mine but, obviously, are not. This assembly is called Blend_RuntimeGeneratedTypeAssembly(Guid goes here). When attempting to load types in this assembly, it throws a type load exception for a number of them. So, some types get proxied, some types are left as God and I intended, and when they mix unnatural acts occur.
For example, the type "Foo" might get a proxy created, but no other types do (TypeLoadExceptions). Then the designer tries to hand one of my real types the proxy (helped by the fact that xaml serialization likes to cast collections to IList, thus shitting on type safety) and you get one of the above exceptions.
I have spent half a week trying to fix this. I've tried a hundred different things, but I can't figure out exactly what is causing it to fail. Suggestions are welcome, TIA.
Solution in two parts:
1) Ensure VS is fully updated. At this point, it means installing the Silverlight 4 tools for Visual Studio 2010. They include the latest updates to the WPF designer. If you're reading this off in the distant future, ignore this one.
2) Hit the properties for your design data files. Clear out "Custom Tool", and set the "Build Action" to either "DesignData" or "DesignTimeDataWithDesignTimeCreatableTypes".
DesignData means that your types cannot be deserialized from xaml directly (due to dependencies or the such), so the designer attempts to create mocks for those types and presents the mocks to your design surface.
DesignTimeDataWithDesignTimeCreatableTypes means that the designer will load your assemblies and deserialize the xaml directly into your types without creating mocks.
This can also be caused by a certain combination of situations that, when combined, cause deserialization to fail.
Essentially if you have
A custom collection, or a collection that doesn't implement IList
That is exposed as a property on your type
Which is defined in a different assembly
you can get this error message as well.
It is very important that your collection property types implement IList (the non-generic one) if you want to serialize them to and from xaml!