In WinForms, the WebBrowser control has a Document property in type HtmlDocument. The HtmlDocument instance has properties/methods like Forms, Links, GetElementsByTagName(), etc. that returns HtmlElementCollection instances. When I iterate over an HtmlElementCollection I am getting HtmlElement instances. These HtmlElement instances have DomElement properties which is a reference to the underlying COM object. My question is, should I call Marshal.ReleaseComObject() method on these HtmlElement instances or does WinForms manage the references internally?
Manual memory management is always a bad idea, particularly so with COM objects. You can get an opinion about it from the experts, the blog post from the Visual Studio team brings the point home pretty well.
Just in case you still think it is a good idea, the Winforms team has already made the decision for you. The interface pointer wrapped by classes like HtmlDocument, HtmlElement, HtmlWindow, HtmlElementCollection etcetera is a private variable of the class. You simply can't get to it, not without breaking every rule in the book anyway.
It is not entirely impossible to have a problem, these wrapper class objects are pretty small so you may have a problem with the garbage collector not running often enough to ensure the underlying COM objects are released. GC.Collect() is the fallback for that. Only use it if necessary.
If you don't call the ReleaseComObject function, the objects will be released automatically by winforms. Msdn says it can be used to control the lifetime of an object, but it is not necessary.
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject.aspx
Related
Does anybody knows why BlockData class doesn't directly implement IContent?
I know that during BlockData is being retrieve from database, proxy created by Castle implements IContent.
If StackOverflow isn't suitable place for this kind of a question, please move it.
Johan Björnfot at EPiServer explains some of the details in this post.
Excerpt:
"In previous versions of CMS was pages (PageData) the only content type that the content repository (traditionally DataFactory) handled. In CMS7 this has changed so now content repository (IContentRepository) handles IContent instances. This means that the requirement for a .NET type to be possible to save/load from content repository is that it implements the interface EPiServer.Core.IContent.
There are some implementations of IContent built into CMS like PageData and ContentFolder (used to group shared block instances) and it is also possible to register custom IContent implementations.If you look at BlockData though you will notice that it doesn’t implement IContent, how is then shared block instances handled?
The answer is that during runtime when a shared block instance is created (e.g. through a call to IContentRepository.GetDefault where T is a type inheriting from BlockData) the CMS will create a new .NET type inheriting T using a technic called mixin where the new generated subclass will implement some extra interfaces (including IContent)."
BlockData does implement IContent as it is intended to work both when added to another content item such as a PageData instance (a.k.a. Local Block), and as a standalone instance (a.k.a.Shared Block). In latter case the interface is added by using a mix-in though Castle Windsor so that it can be referenced.
The decision for this construct was based on wanting to be able to use the same rendering templates regardless if a block is local or shared. Therefor the choice stood between having a large number of empty properties on local blocks or the current solution using mixins. Both options were tested and mixins was selected as the preferred solution even though it's not a perfect one.
BlockData "does implement IContent", just do:
var myContent = (IContent)myBlock;
But, if you're by any chance handling a Block which itself is a property (not a ContentReference), that cast will throw an exception.
This will be true for 100% of all cases (... using Math.Round).
In my project I'm using C++/CLI and Windows Forms. I have two Forms. One is executed in main()
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew FormA);
Another FormB is executed from the instance of FormA
FormB^ fb = gcnew FormB();
fb->Show();
I need to change components of FormB from FormA. Normally they are in private: section of class FormB. Is there any nice way to do that different from simply making them all public? In Native C++ I would use friend class but it's not allowed in C++/CLI.
C++/CLI has an access modifier that native C++ does not have. You are looking for internal:
Empowered by the strong support for modules in .NET. It is broader than friend but you have a pretty hard guarantee that whomever is messing with your private parts is never more than a few cubicles away from yours. Code that accesses internal members must be compiled into the same assembly. So your FormB class must be in the same project as your FormA class. The common case.
If you need the equivalent of friend across modules then you need the [InternalsVisibleTo] attribute. Exposing members with a public property would be another common way.
While providing public access to FormB's members may seem like a quick and easy solution, I would advise you to add some methods on FormB to perform said actions.
This way, you can call those methods from FormA, and at the same time retain proper encapsulation.
Hope this helps.
I`m learning the concepts of composite applications.
I created prism application using unity container.
One of my regions configed as content control - In this Region, I want show just single view.
I`m using view injection in the next way:
object lastView;
// View injection
IRegion region = regionManager.Regions["MainRegion"];
var ordersView = container.Resolve<OrdersView>();
lastView = ordersView;
region.Add(ordersView, "OrdersView");
region.Activate(ordersView);
This the views in this region are switched frequently.
Before Im switching view Im using region.remove(lastView)
and than adding the next view like the code above.
Im not sure that its a good implementation, I have a few questions:
When I`m using region.remove method, Is the removed view being disposed?
Because if not after long run I will have serious memory leaks.
What is the best way implement single view in a region while avoiding memory leaks?
Thanks
By memory leaks I guess you're talking about whether the Garbage Collector is going to collect that view or not - e.g. is the container still referencing it when you remove it.
The decision on whether to keep a reference of the object after it's resolved is based on the type of the LifeTime Manager you used when you registered that object.
To answer your question shortly - The default LifeTime manager used with RegisterType is the TransientLifetimeManager, in which Unity creates a new instance of the requested type for each call to the Resolve or ResolveAll method.
What you're probably looking for is the ExternallyControlledLifetimeManager:
This lifetime manager allows you to register type mappings and existing objects with the container so that it maintains only a weak reference to the objects it creates when you call the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes based on attributes or constructor parameters within that class. This allows other code to maintain the object in memory or dispose it and enables you to maintain control of the lifetime of existing objects or allow some other mechanism to control the lifetime.
If you want to control the lifetime of your views, consider using the RegisterType with this LifeTime Manager.
Also, according to this article - The only lifetime managers which calls Dispose on resolved instances are ContainerControlledLifetimeManager (which creates singelton instances) and HierarchicalLifetimeManager. In these cases, the Dispose is only called when the lifetime manager is disposed.
I'm working on a out of browser Silverlight app that provides some MS Office Communicator 2007 controls. I'm using the Automation SDK. The docs that were installed with the SDK state that there's a MyGroups property in the IMessenger2 interface, which will return the groups that a user has defined, but when I try to use it, I get a NotImplementedException. Here's the code that I'm using:
dynamic communicator = AutomationFactory.CreateObject("Communicator.UIAutomation");
communicator.AutoSignin();
foreach (dynamic g in communicator.MyGroups)
{
//Do something with the group
}
If I replace MyGroups with MyContacts, I can get the contact list just fine. Do I have to do something different to access properties in the IMessenger2 interface? I've seen a few things on the web that say that MyGroups was deprecated for Windows Messenger, but from the docs, it seems like it should be available for MS Office Communicator.
If I can't use MyGroups, is there another way to get the groups that a user has created?
The problem here is that the MyGroups property is marked as NotScriptable, meaning you can't call it in the way you are doing i.e. using the AutomationFactory. For security reasons, some properties and methods in the Automation API are not scriptable - this is to avoid malicious pages automating Communicator and carrying out certain tasks without you knowing.
It looks like the COM interop in Silverlight is treated in the same way as e.g. creating and calling the API from VBScript, so you won't be able to access any of the non-scriptable properties and methods. See the reference for details of which properties and methods are not scriptable.
I'm guessing this is going to seriously hobble your app. I think what's hurting you is the decision to go with Silverlight OOB. Is there any way you could use WPF (or even winforms) rather than Silverlight? If you did this, you could reference the API directly, and have full access to all properties/methods.
Otherwise, I can't think of too many options. You can't trap the OnContactAddedToGroup event, as this is not scriptable.
It might be possible to wrap the API with a .NET assembly, and expose it via COM, then instantiate it in the same way - but the Not Scriptable might still be respected in that case, so it won't buy you anything. Hard to say without trying it, and still a fairly horrible solution.
Edit: I've just given the wrapper method a try (needed to do something similar as a proof of concept for a customer), and it seems to work. This is the way I did it:
Create a new .NET class library. Define a COM interface:
[ComVisible(true)]
[Guid("8999F93E-52F6-4E29-BA64-0ADC22A1FB11")]
public interface IComm
{
string GetMyGroups();
}
Define a class that implements that interface (you'll need to reference CommunicatorAPI.dll from the SDK):
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[GuidAttribute("C5C5A1A8-9BFB-4CE5-B42C-4E6688F6840B")]
[ProgId("Test.Comm.1")]
public class Comm : IComm
{
public string GetMyGroups()
{
var comm = new CommunicatorAPI.MessengerClass();
var groups = comm.MyGroups as IMessengerGroups;
return string.Join(", ", groups.OfType<IMessengerGroup>().Select(g => g.Name).ToArray());
}
}
Build, and register using RegAsm. Then call from the OOB silverlight app:
dynamic communicator = AutomationFactory.CreateObject("Test.Comm.1");
MessageBox.Show(communicator.GetMyGroups());
Note, the same technique also works using the Lync API:
public string GetMyGroups()
{
var comm = LyncClient.GetClient();
return string.Join(", ", comm.ContactManager.Groups.Select(g => g.Name).ToArray());
}
Although this works, I can't really say whether it's a good practice, as it's working around a security restriction which was presumably there for a good reason. I guess the worst that could happen is that a malicious web page could potentially use the component, if it knew the ProgId of the control.
Edit: Also, using this method you'd need to be careful about memory leaks, e.g. make sure you're releasing COM objects when you're finished with them - easy enough to do, just needs a little discipline ;o)
What are the pros and cons of having multiple inheritance?
And why don't we have multiple inheritance in C#?
UPDATE
Ok so it is currently avoided because of the issue with clashes resolving which parent method is being called etc. Surely this is a problem for the programmer to resolve. Or maybe this could be resolve simularly as SQL where there is a conflict more information is required i.e. ID might need to become Sales.ID to resolve a conflict in the query.
Here is a good discussion on the pitfalls of multiple inheritance:
Why should I avoid multiple inheritance in C++?
Here is a discussion from the C# team on why they decided not to allow multiple inheritance:
http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85562.aspx
http://dotnetjunkies.com/WebLog/unknownreference/archive/2003/09/04/1401.aspx
It's just another tool in the toolbox. Sometimes, it is exactly the right tool. If it is, having to find a workaround because the language actually prohibits it is a pain and leads to good opportunities to screw it up.
Pros and cons can only be found for a concrete case. I guess that it's quite rare to actually fit a problem, but who are the language designers to decide how I am to tackle a specific problem?
I will give a pro here based on a C++ report-writer I've been converting to REALbasic (which has interfaces but only single-inheritance).
Multiple inheritance makes it easier to compose classes from small mixin base classes that implement functionality and have properties to remember state. When done right, you can get a lot of reuse of small code without having to copy-and-paste similar code to implement interfaces.
Fortunately, REALbasic has extends methods which are like the extension methods recently added to C# in C# 3.0. These help a bit with the problem, especially as they can be applied to arrays. I still ended up with some class hierarchies being deeper as a result of folding in what were previously multiply-inherited classes.
The main con is that if two classes have a method with the same name, the new subclass doesn't know which one to call.
In C# you can do a form of multiple inheritance by including instances of each parent object within the child.
class MyClass
{
private class1 : Class1;
private class2: Class2;
public MyClass
{
class1 = new Class1;
class2 = new Class2;
}
// Then, expose whatever functionality you need to from there.
}
When you inherit from something you are asserting that your class is of that (base) type in every way except that you may implement something slightly differently or add something to it, its actually extremely rare that your class is 2 things at once. Usually it just has behavour common to 2 or more things, and a better way to describe that generally is to have your class implement multiple interfaces. (or possibly encapsulation, depending on your circumstances)
It's one of those help-me-to-not-shoot-myself-in-the-foot quirks, much like in Java.
Although it is nice to extend fields and methods from multiple sources (imagine a Modern Mobile Phone, which inherits from MP3 Players, Cameras, Sat-Navs, and the humble Old School Mobile Phone), clashes cannot be resolved by the compiler alone.