How to find a class tagged with postsharp aspect via reflection - reflection

I tryout some ways to use postsharp
The definition of one of my custom aspects looks like:
<Serializable> _
<MulticastAttributeUsage(PersistMetaData:=True)> _
Public Class StringChecker
Inherits LocationInterceptionAspect
Public Overrides Sub OnGetValue(ByVal args As LocationInterceptionArgs)
MyBase.OnGetValue(args)
..... ..... .....
When I try to find all classes that are tagged with the attribute / aspect , the result ist always empty.
I use this code to discover the assemblys at runtime:
Dim targetClasses As IEnumerable(Of Type) = From asm In AppDomain.CurrentDomain.GetAssemblies().Where(Function(A) A.FullName.Contains("MyNameSpace")) _
.SelectMany(Function(A) A.GetTypes()) _
.Where(Function(T) T.IsDefined(GetType(StringChecker), True))
When I use for testing proposals, a normal atttribute, the query delivers the espected types.
Hoppefully some can give me a hint what I have to do.
edit: It looks like the custom attributes can only be found in the class propertys..
Regards,
Markus

There are two ways to do it:
Use ReflectionSearch but it does not retrieve aspects added with IAspectProvider.
Use IAspectRepositoryService

Related

How to create a class to use with LINQ?

I'm trying to create a simple class with variables in that I can assign data to and then use LINQ to update a database.
My class looks like this:
Public Class GoalDetails
Inherits System.Object
Public Id As Integer
Public GoalTime As Integer
Public Scorer As String
Public HomeAway As String
End Class
My code to assign variables and then insert is:
Dim goalsToDb = New GoalDetails()
goalsToDb.Id = 1
goalsToDb.GoalTime = 87
goalsToDb.Scorer = "W Rooney"
goalsToDb.HomeAway = "Home"
db.Goals.InsertOnSubmit(goalsToDb)
db.SubmitChanges()
I get the message "Value of type 'GoalDetails' cannot be converted to 'Goal'.
I'm using the same code with another class that is in a third party DLL and it works, but of course I can't see the code of that class to see how it differs from mine.
This is a statically typed language. Even if two types are conceptually similar they are still entirely different types. You can't use them interchangeably.
This property:
db.Goals
Is a collection of a given type. (Possibly named Goal?) You can only add items of that type to that collection. Something like this:
Dim goalsToDb = New Goal() ' or whatever the type is called, you'd have to confirm
goalsToDb.Id = 1
goalsToDb.GoalTime = 87
goalsToDb.Scorer = "W Rooney"
goalsToDb.HomeAway = "Home"
db.Goals.InsertOnSubmit(goalsToDb)
db.SubmitChanges()
You can create custom classes to hold your data within your application. But when using your data access framework's generated code (Entity Framework? LINQ to SQL?) then you have to use the types generated by that framework. So if you use a custom class throughout your application then you'd need to convert its values to the database class when interacting with the database.
You seem to be confusing the two types Goal and GoalDetails. You can not use db.Goals.InsertOnSubmit() to insert data in GoalDetails table. In order to do so, you need to come up with something like db.GoalDetails.InsertOnSubmit() which will take an object of GoalDetails and insert into GoalDetails table.
Also, if you want to see a class from 3rd party DLL, you can use IL disassemblers like ILSpy

Structuring Class with constructor

I have a Class with a Constructor. My constructor takses all the required parameter, then I use the parameters to return another class.
Public Class SearchResults()
private id as int
Sub New(id) ' Constructor
getResults(id)
End Sub
Public Function getResults(byval id as int) as List(of Products)
........
return list (of products)
End Function
End
Then in my page I want to get all the productts.
Dim s = new SearchResults( 1 )
Dim p as list(of Products) = s.getResults()
----now I can do for Each on this
This works for me, but I do have a feeling there has to be a better way of doing it, I want to stick to the best standards. do you guys think, this is the best approach or it could be improved? My designers will be utilizing this class within their projects...so i would love to make it as simple as possible for them.
or maybe how to create an Collection of a Class...for example Class Product and its collection Class Products, Where Products is the Collection of Project Class.
There are three ways to do what you want:
1) You can load the results and store them in the object on the constructor
2) You can store the ID in the object and call the function to get the results when needed
3) You can make the function static and pass in the ID as well as the collection (or resource needed to get the collection) and not use an object at all.
Depending on what you need, most likely either 1 or 3 are going to be best. If you plan on reusing the object for other methods than just the one function, then option 1 is the best, but if you just need the 1 function, go with option 3 like this:
Public Class SearchResults
Public Static Function getResults(ByVal id As int) As List(Of Products)
'........
return list (of products)
End Function
End Class
You could make the getResults method static possibly and cut out having to create a class instance to call it.
I personally would declare the getResults method as Shared so that you don't have to create a SearchResults object just to access that method. This would also allow you to call the method again with another ID without having to create another object.

fluent nhibernate Exception error

am trying to implement fluent nhibernate in MVC project...there were no build errors... but when i run the project i get this exception
System.Xml.Schema.XmlSchemaValidationException: The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has incomplete content. List of possible elements expected: 'meta, subselect, cache, synchronize, comment, tuplizer, id, composite-id' in namespace 'urn:nhibernate-mapping-2.2'.
have no idea what am doing wrong here... the following is the code for opening session factory...
Private Function CreateSessionFactory() As ISessionFactory
Dim sessionFactoryObject As ISessionFactory
sessionFactoryObject = Fluently.Configure().Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005.ConnectionString("Data Source=.\sqlexpress;Initial Catalog=Designs;User ID=sa;Password=root")).Mappings(Function(x) x.FluentMappings.Add(GetType(DesignMap))).BuildSessionFactory()
Return sessionFactoryObject
End Function
this is really driving me nuts....thanks in advance...:)
update-the mappings
the design table map
Public Class DesignMap
Inherits ClassMap(Of Design)
Public Sub DesignMap()
Table("DesignList")
Id(Function(x) x.DesignId)
Map(Function(x) x.DesignType)
References(Function(x) x.Designer, "DesignerId")
End Sub
End Class
the designer table map
Public Class DesignerMap
Inherits ClassMap(Of Designer)
Public Sub DesignerMap()
Table("DesignerList")
Id(Function(x) x.DesignerId)
Map(Function(x) x.DesignerName)
Map(Function(x) x.DesignerCompany)
HasMany(Function(x) x.DesignersDesigns)
End Sub
End Class
new edit-- the entity property looks like this
Public Overridable Property Name() As String
Get
Return _name
End Get
Protected Set(ByVal value As String)
_name = value
End Set
End Property
am i going the right way..?
I'm not quite sure as the mappings seem ok. I can see one error tough, you have only mapped one of your classes:
.Mappings(Function(x) x.FluentMappings.Add(GetType(DesignMap)))
That should not cause this type of error tough. If you add both your mappings and call the method .ExportTo(#"C:\your\export\path") you will get the actual xml mappings. This way it's easier to see the error. You can do that like this:
.Mappings(Function(x) x.FluentMappings.Add(GetType(DesignMap)).Add(GetType(DesignerMap
).ExportTo(#"C:\your\export\path"))
You can also use the method AddFromAssemblyOf (or some other. There is a few choices) if you don't want to add the mappings one by one.
Try exporting the mappings and see if you can find any error. Or you can post the xml mappings and someone else might find something.
There are several things that can cause this. When using automappings, you will get this if you incorrectly specify the assemblies and namespaces to look in. Other things (more likely in your case) that could cause it, are entity properties that aren't marked as public virtual, having an entity constructor with arguments, but neglecting to make a default constructor, or inheriting your entities from a base class.
I would probably first check to make sure all of your entity properties are "public virtual".
found the problem...the constructor for the map was wrong...it should be like this...
Public Class DesignMap
Inherits ClassMap(Of Design)
Public Sub New()
Table("DesignList")
Id(Function(x) x.DesignId)
Map(Function(x) x.DesignType)
References(Function(x) x.Designer, "DesignerId")
End Sub
End Class
problems of working in both C# and vb.net at the same time i guess..!!
and "Matthew Talbert" was correct...making all the properties Overrideable is important..
thanks guys...:)

Exposing an Enum to a WebService's client JavaScript without using it in a WebMethod?

I'm building an ASP.NET 3.5 application and would like to expose an enum I have in my WebService class without using it as a parameter in once of my WebMethods.
I have a really simple example to illustrate what I want... Let's say I have the following WebService (I'll call it Agent.asmx):
<System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class Agent
Inherits System.Web.Services.WebService
<WebMethod(EnableSession:=True)> _
Public Function DoSomething(ByVal doWhat As WhatEnum) As Boolean
Return ...
End Function
End Class
Public Enum WhatEnum
AskStackOverflowQuestion
PhoneAFriend
FiftyFifty
End Enum
Because I used the Enum in one of the WebMethods, it will output the following in the JavaScript in generates for the Agent when the WebService is referenced in my .aspx page (from http://localhost/Agent.asmx/js):
if (typeof(SomeNamespace.WhatEnum) === 'undefined') {
SomeNamespace.WhatEnum = function() { throw Error.invalidOperation(); }
SomeNamespace.WhatEnum.prototype = { AskStackOverflowQuestion: 0,PhoneAFriend: 1,FiftyFifty: 2}
SomeNamespace.WhatEnum.registerEnum('SomeNamespace.WhatEnum', true);
}
Now I can go and use these enums wherever I want on the client side. Now, that's all fine and dandy, but I have another Enum in my Agent that I don't actually use in any of the WebMethods, which I would also like to be automatically exposed in the Agent's JavaScript. Is there a way, perhaps an attribute or something I could use, to cause it to be included?
If not, my fallback solution is to just create a dummy method with my Enum as a parameter so that it will be available, and simply never call it from the JS, though I'd rather not litter the code. Thanks!
Obviously the easiest solution would be to create the dummy method. I guess I am wondering why you need an enumeration from your web service to be available in your JavaScript if you never pass that enumeration to the service or receive it from the service in any way.
Do you at least use the enum in the service? Otherwise, it doesn't belong there.
I belive you should look at the [XmlInclude] attribute.

asp.net - passing generic lists

I have a utility class that takes a generic list as a parameter.
Code looks like:
Function DoStuff(collection as Object, elt as Object)
...
collection.Add(elt)
...
End Function
This is called with:
DoStuff( List(Of Foo), new Foo() )
DoStuff( List(Of Bar), new Bar() )
There are about a dozen different types.
Currently, passing as Object results in a Late bound resolution warning, although it runs fine.
I've tried different ways to pass in collection and elt (Foo and Bar both extend a base class) but can't seem to figure out the "proper" way to do it.
Ideas?
I think you're looking for something like this.
Public Sub DoStuff(Of T)(collection As List(Of T), elt As T)
...
collection.Add(elt)
...
End Function
The answers by womp and Qua are I think the correct ones, however if your 12 types all inherit from some common base class (as your original question suggests) you can write the method such that it works with your types, and only your types as such:
Public Sub DoStuff(Of T As YourBaseClass)(collection As List(Of T), elt As T)
...
collection.Add(elt)
...
End Sub
This way the method works only for types which inherit from YourBaseClass.
You should always strive to built/use strongly typed code. Imagine what would happen if an integer was passed as the collection object - You would have to manually check for the type of the variable. Even worse though, the user of your method would have to look up in the documentation what kind of object your method required as it's first parameter.
You should go by the approach suggested by womp, or even better you should make your parameter require an object that extends the generic collection interface, ICollection(Of T):
Public Function DoStuff(Of T)(collection As ICollection(Of T), elt As T) As stuff
...
collection.Add(elt)
...
End Function
since this would allow the user of the method to pass not only lists, but also all other classes that inheritage the ICollection(Of T) interface (synchronizedCollection, HashSet, LinkedList, or custom classes ect.) which is really the power of OO programming.

Resources