WF4 Business Rules - workflow-foundation-4

I want to pass a object to workflow as input parameter, without creating instance of it, as this object is already filled up with lot of sub-objects, and I want to run lot of rules on that object. I want to use
WorkflowInvoker.Invoker(this); Is this possible in Windows Workflow Foundation 4.0, If so, what should I keep in InArguments as the type?
Thanks In Advance,

Thanks for your input....
Sorry, I think I haven't kept the question correctly, I had a business class used by bank customers, class is like this,
public partial class BankName.DTOS.clsCardDetails : BaseClass
{
public string _mBankStatusCode;
protected override string IsCreditCard(HttpContext ctx)
{
Status = ctx.Request.Form["Trans_Status"];
_mBankStatusCode = Status.ToString();
}
}
Now, I have to pass this class object to workflow foundation, I should not create new instance of this class in workflow again. Because in workflow, I want to get the status, so ideally what I thought of passing to workflow is object of "BankName.DTOS.clsCardDetails". That is my question.
InArguments<> to workflow is object of BankName.DTOS.clsCardDetails

Arguments passed into a workflow need to be put into a dictionary and the dictionary is passed into the workflow.
var dictionary = new Dictionary<string, object> { { "BankName", _bankNameObject } };
WorkflowInvoker.Invoke(this, dictionary);
The key must have the same name as your InArgument and your object must have the same type as your InArgument.
You can pass as many arguments as you like into the workflow via the dictionary.
See http://blogs.msdn.com/b/rjacobs/archive/2011/05/26/passing-arguments-to-workflow-activities-again.aspx

Related

Reflection: No functions in LibraryMirror

I'm trying to build an entity manager in Dart which uses reflection. The idea is that the method getById(String id, String returnClass) calls a method _get[returnClass]ById(String id).
To accomplish this I'm using dart:mirrors and try to determine if my entity manager object has such a method and call it then. Unfortunately the LibraryMirror doesn't contain any functions.
class EntityMgr {
Object getById(String id, String returnClass) {
InstanceMirror result = null;
String methodName = '_get'+returnClass+'ById';
// Check if a method '_get[returnClass]Byid exists and call it with given ID
if(_existsFunction(methodName)) {
Symbol symbol = new Symbol(methodName);
List methodParameters = new List();
methodParameters.add(id);
result = currentMirrorSystem().isolate.rootLibrary.invoke(symbol, methodParameters);
}
return result;
}
Product _getProductById(String id) {
return new Product();
}
bool _existsFunction(String functionName) {
return currentMirrorSystem().isolate.rootLibrary.functions.containsKey(functionName);
}
}
The mirrors library has changed significantly since this response and no longer reflects the api mentioned in this answer
Isolate's are for concurrent programming and you probably don't have any isolates running. Where you want to look is currentMirrorSystem().libraries, or you can use currentMirrorSystem().findLibrary(new Symbol('library_name')).
You need to know the library because a function or class with the same Symbol could me in different libraries but have completely different signatures.
how to invoke class form dart library string or file shows how to get the class mirror from the library and class name.
The ClassMirror contains the methods, the getters and the setters. The methods mirror does not contain the getters or setters.
final Map<Symbol, MethodMirror> methods
final Map<Symbol, MethodMirror> getters
final Map<Symbol, MethodMirror> setters
That being said, you might want to check out the dart serialization at http://api.dartlang.org/docs/bleeding_edge/serialization.html since it might already do exactly what you're trying to do.

How to dispose data context after usage

I have a member class that returned IQueryable from a data context
public static IQueryable<TB_Country> GetCountriesQ()
{
IQueryable<TB_Country> country;
Bn_Master_DataDataContext db = new Bn_Master_DataDataContext();
country = db.TB_Countries
.OrderBy(o => o.CountryName);
return country;
}
As you can see I don't delete the data context after usage. Because if I delete it, the code that call this method cannot use the IQueryable (perhaps because of deferred execution?). How to force immediate execution to this method? So I can dispose the data context..
Thank you :D
The example given by Codeka is correct, and I would advice writing your code with this when the method is called by the presentation layer. However, disposing DataContext classes is a bit tricky, so I like to add something about this.
The domain objects generated by LINQ to SQL (in your case the TB_Countries class) often contain a reference to the DataContext class. This internal reference is needed for lazy loading. When you access for instance list of referenced objects (say for instance: TB_Country.States) LINQ to SQL will query the database for you. This will also happen with lazy loaded columns.
When you dispose the DataContext, you prevent it from being used again. Therefore, when you return a set of objects as you've done in your example, it is impossible to call the States property on a TB_Country instance, because it will throw a ObjectDisposedException.
This does not mean that you shouldn't dispose the DataContext, because I believe you should. How you should solve this depends a bit on the architecture you choose, but IMO you basically got two options:
Option 1. Supply a DataContext to the GetCountriesQ method.
You normally want to do this when your method is an internal method in your business layer and it is part of a bigger (business) transaction. When you supply a DataContext from the outside, it is created outside of the scope of the method and it shouldn't dispose it. You can dispose it at a higher layer. In that situation your method basically looks like this:
public static IQueryable<TB_Country> GetCountriesQ(
Bn_Master_DataDataContext db)
{
return db.TB_Countries.OrderBy(o => o.CountryName);
}
Option 2. Don't return any domain objects from the GetCountriesQ method.
This solution is useful when the method is a public in your business layer and will be called by the presentation layer. You can wrap the data in a specially crafted object (a DTO) that contains only data and no hidden references to the DataContext. This way you have full control over the communication with the database and you can dispose the DataContext as you should. I've written more about his on SO here. In that situation your method basically looks like this:
public static CountryDTO[] GetCountriesQ()
{
using (var db = new Bn_Master_DataDataContext())
{
var countries;
from country in db.TB_Countries
orderby country.CountryName
select new CountryDTO()
{
Name = country.CountryName,
States = (
from state in country.States
order by state.Name
select state.Name).ToList();
};
return countries.ToArray();
}
}
public class CountryDTO
{
public string Name { get; set; }
public List<StateDTO> States { get; set; }
}
As you will read here there are some smart things you can do that make using DTOs less painful.
I hope this helps.
You can convert the queryable to a list, like so:
public static List<TB_Country> GetCountriesQ()
{
using(var db = new Bn_Master_DataDataContext())
{
return db.TB_Countries
.OrderBy(o => o.CountryName).ToList();
}
}

How do I create a shallow copy of an object so that it may be serialize and sent via a web method call?

I would like to serialize the properties of the HttpBrowserCapibilities object so that it may be returned via a web method call. Currently the object cannot be serialized:
Cannot serialize member System.Web.Configuration.HttpCapabilitiesBase.Capabilities of type System.Collections.IDictionary, because it implements IDictionary.
...which is understandable. However, I would like to simply copy out the properties and their values to a hierarchy, i.e.
<HttpBrowserCapabilities>
<IsMobile>true</IsMobile>
</HttpBrowserCapabilities>
I'm starting to think I would need to use reflection to copy this object, but I haven't reached a conclusion. Does anyone have any suggestions to keep this simple?
Thanks,
George
Originally I posted an answer using XmlDocument, but I glossed over some of the web method stuff and didn't realize you were really trying to map a DTO.
Reflection sounds complicated but it really isn't. The following snippet will do what you want:
public static void Populate(object dest, IDictionary dictionary)
{
Type t = dest.GetType();
foreach (object key in dictionary)
{
PropertyInfo prop = t.GetProperty(key.ToString(),
BindingFlags.Instance | BindingFlags.Public);
if ((prop != null) && prop.CanWrite)
{
object value = dictionary[key];
prop.SetValue(dest, value, null);
}
}
}
Then invoke this as:
BrowserCapsDto dto = new BrowserCapsDto();
Populate(dto, Capabilities); // Capabilities is the real BrowserCaps
It's pretty easy because you already have an IDictionary and thus you already know all of the possible names you can map; you don't actually need to use any reflection on the source, just the destination.

strongly typed sessions in asp.net

Pardon me if this question has already been asked. HttpContext.Current.Session["key"] returns an object and we would have to cast it to that particular Type before we could use it. I was looking at various implementations of typed sessions
http://www.codeproject.com/KB/aspnet/typedsessionstate.aspx
http://weblogs.asp.net/cstewart/archive/2008/01/09/strongly-typed-session-in-asp-net.aspx
http://geekswithblogs.net/dlussier/archive/2007/12/24/117961.aspx
and I felt that we needed to add some more code (correct me if I was wrong) to the SessionManager if we wanted to add a new Type of object into session, either as a method or as a separate wrapper. I thought we could use generics
public static class SessionManager<T> where T:class
{
public void SetSession(string key,object objToStore)
{
HttpContext.Current.Session[key] = objToStore;
}
public T GetSession(string key)
{
return HttpContext.Current.Session[key] as T;
}
}
Is there any inherent advantage in
using
SessionManager<ClassType>.GetSession("sessionString")
than using
HttpContext.Current.Session["sessionString"] as ClassType
I was also thinking it would be nice
to have something like
SessionManager["sessionString"] = objToStoreInSession,
but found that a static class cannot have an indexer. Is there any other way to achieve this ?
My thought was create a SessionObject which would store the Type and the object, then add this object to Session (using a SessionManager), with the key. When retrieving, cast all objects to SessionObject ,get the type (say t) and the Object (say obj) and cast obj as t and return it.
public class SessionObject { public Type type {get;set;} public Object obj{get;set;} }
this would not work as well (as the return signature would be the same, but the return types will be different).
Is there any other elegant way of saving/retrieving objects in session in a more type safe way
For a very clean, maintainable, and slick way of dealing with Session, look at this post. You'll be surprised how simple it can be.
A downside of the technique is that consuming code needs to be aware of what keys to use for storage and retrieval. This can be error prone, as the key needs to be exactly correct, or else you risk storing in the wrong place, or getting a null value back.
I actually use the strong-typed variation, since I know what I need to have in the session, and can thus set up the wrapping class to suit. I've rather have the extra code in the session class, and not have to worry about the key strings anywhere else.
You can simply use a singleton pattern for your session object. That way you can model your entire session from a single composite structure object. This post refers to what I'm talking about and discusses the Session object as a weakly typed object: http://allthingscs.blogspot.com/2011/03/documenting-software-architectural.html
Actually, if you were looking to type objects, place the type at the method level like:
public T GetValue<T>(string sessionKey)
{
}
Class level is more if you have the same object in session, but session can expand to multiple types. I don't know that I would worry about controlling the session; I would just let it do what it's done for a while, and simply provide a means to extract and save information in a more strongly-typed fashion (at least to the consumer).
Yes, indexes wouldn't work; you could create it as an instance instead, and make it static by:
public class SessionManager
{
private static SessionManager _instance = null;
public static SessionManager Create()
{
if (_instance != null)
return _instance;
//Should use a lock when creating the instance
//create object for _instance
return _instance;
}
public object this[string key] { get { .. } }
}
And so this is the static factory implementation, but it also maintains a single point of contact via a static reference to the session manager class internally. Each method in sessionmanager could wrap the existing ASP.NET session, or use your own internal storage.
I posted a solution on the StackOverflow question is it a good idea to create an enum for the key names of session values?
I think it is really slick and contains very little code to make it happen. It needs .NET 4.5 to be the slickest, but is still possible with older versions.
It allows:
int myInt = SessionVars.MyInt;
SessionVars.MyInt = 3;
to work exactly like:
int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;

Access/use the same object during a request - asp.net

i have a HttpModule that creates an CommunityPrincipal (implements IPrincipal interface) object on every request. I want to somehow store the object for every request soo i can get it whenever i need it without having to do a cast or create it again.
Basically i want to mimic the way the FormsAuthenticationModule works.
It assigns the HttpContext.User property an object which implements the IPrincipal interface, on every request.
I somehow want to be able to call etc. HttpContext.MySpecialUser (or MySpecialContext.MySpecialUser - could create static class) which will return my object (the specific type).
I could use a extension method but i dont know how to store the object so it can be accessed during the request.
How can this be achieved ?
Please notice i want to store it as the specific type (CommunityPrincipal - not just as an object).
It should of course only be available for the current request being processed and not shared with all other threads/requests.
Right now i assign my CommunityPrincipal object to the HttpContext.User in the HttpModule, but it requires me to do a cast everytime i need to use properties on the CommunityPrincipal object which isnt defined in the IPrincipal interface.
I'd recommend you stay away from coupling your data to the thread itself. You have no control over how asp.net uses threads now or in the future.
The data is very much tied to the request context so it should be defined, live, and die along with the context. That is just the right place to put it, and instantiating the object in an HttpModule is also appropriate.
The cast really shouldn't be much of a problem, but if you want to get away from that I'd highly recommend an extension method for HttpContext for this... this is exactly the kind of situation that extension methods are designed to handle.
Here is how I'd implement it:
Create a static class to put the extension method:
public static class ContextExtensions
{
public static CommunityPrinciple GetCommunityPrinciple(this HttpContext context)
{
if(HttpContext.Current.Items["CommunityPrinciple"] != null)
{
return HttpContext.Current.Items["CommunityPrinciple"] as CommunityPrinciple;
}
}
}
In your HttpModule just put the principal into the context items collection like:
HttpContext.Current.Items.Add("CommunityPrincipal", MyCommunityPrincipal);
This keeps the regular context's user property in the natural state so that 3rd party code, framework code, and anything else you write isn't at risk from you having tampered with the normal IPrincipal stroed there. The instance exists only during the user's request for which it is valid. And best of all, the method is available to code as if it were just any regular HttpContext member.... and no cast needed.
Assigning your custom principal to Context.User is correct. Hopefully you're doing it in Application_AuthenticateRequest.
Coming to your question, do you only access the user object from ASPX pages? If so you could implement a custom base page that contains the cast for you.
public class CommunityBasePage : Page
{
new CommunityPrincipal User
{
get { return base.User as CommunityPrincipal; }
}
}
Then make your pages inherit from CommunityBasePage and you'll be able to get to all your properties from this.User.
Since you already storing the object in the HttpContext.User property all you really need to acheive you goal is a Static method that acheives your goal:-
public static class MySpecialContext
{
public static CommunityPrinciple Community
{
get
{
return (CommunityPrinciple)HttpContext.Current.User;
}
}
}
Now you can get the CommunityPrinciple as:-
var x = MySpecialContext.Community;
However it seems a lot of effort to got to avoid:-
var x = (CommunityPrinciple)Context.User;
An alternative would be an Extension method on HttpContext:-
public static class HttpContextExtensions
{
public static CommunityPrinciple GetCommunity(this HttpContext o)
{
return (CommunityPrinciple)o.User;
}
}
The use it:-
var x = Context.GetCommunity();
That's quite tidy but will require you to remember to include the namespace where the extensions class is defined in the using list in each file the needs it.
Edit:
Lets assume for the moment that you have some really good reason why even a cast performed inside called code as above is still unacceptable (BTW, I'd be really interested to understand what circumstance leads you to this conclusion).
Yet another alternative is a ThreadStatic field:-
public class MyModule : IHttpModule
{
[ThreadStatic]
private static CommunityPrinciple _threadCommunity;
public static CommunityPrinciple Community
{
get
{
return _threadCommunity;
}
}
// Place here your original module code but instead of (or as well as) assigning
// the Context.User store in _threadCommunity.
// Also at the appropriate point in the request lifecyle null the _threadCommunity
}
A field decorated with [ThreadStatic] will have one instance of storage per thread. Hence multiple threads can modify and read _threadCommunity but each will operate on their specific instance of the field.

Resources