Friday, August 24, 2018

How should I inherit IDisposable?

Class names have been changed to protect the innocent.

If I have an interface named ISomeInterface. I also have classes that inherit the interface, FirstClass and SecondClass. FirstClass uses resources that must be disposed. SecondClass does not.

So the question is, where should I inherit from IDisposable? Both of the following options seem less than ideal:

1) Make FirstClass inherit IDisposable. Then, any code that deals with ISomeInterfaces will have to know whether or not to dispose of them. This smells like tight coupling to me.

2) Make ISomeInterface inherit IDisposable. Then, any class that inherits from it must implement IDisposable, even if there is nothing to dispose. The Dispose method would essentially be blank except for comments.

#2 seems like the correct choice to me, but I'm wondering if there are alternatives.

Solved

If there is a reasonable chance that an abstract entity (interface or abstract class) might need to be disposable, it should implement it. Stream, for example doesn't itself need IDisposable, nor does IEnumerator...

An abstract base class may be simpler, as you can have a default (empty) implementation of Dispose() then, and possibly the finalizer / Dispose(bool) pattern, i.e.

void IDisposable.Dispose() { Dispose(true); GC.SuppressFinalize(this); }
protected virtual void Dispose(bool disposing) {}
~BaseType() {Dispose(false);}

If you know some implementations of ISomeInterface require disposal, then the interface should inherit IDisposable, even if concrete implementations of the interface don't have anything to dispose of.

For instance, in the BCL, IDataReader implements IDisposable, even though one could certainly imagine data reader implementations that don't have external resources that need to be disposed of.


It depends on your interface, but I'd lean toward #2. If you have two implementations of ISomeInterface and only one needs disposing, then there's the possibility you need to refactor.

In general when you're binding to an interface, it's better to have that interface inherit IDisposable rather than the base class; if your interface doesn't inherit IDisposable, you must cast to IDisposable to dispose of the object, and that runs the risk of an InvalidCast...


If you want all your code to deal with ISomeInterfaces generically, then yes they should all be disposable.

If not, then the code that creates FirstClass should dispose it:

using (FirstClass foo = new FirstClass()) {
    someObjectThatWantsISomeInterface.Act(foo);
}

otherwise, you could always use something like this extension method:

public static void DisposeIfPossible(this object o) {
    IDisposable disp = o as IDisposable;
    if (disp != null)
        disp.Dispose();
}

// ...
someObject.DisposeIfPossible(); // extension method on object

I should also mention that I would prefer a template base class approach to this. I stubbed this out in this blog on building disposable things properly.


My advice is go to the root and not directly to a concrete class. Point 2 is to the root and you are driven by some sort of contract by FirstClass. If you know that classes must implement some interface then you want to ensure that the interface they sign a contract iwth inherits IDisposable


All of the answers written so far miss a key point: it's only necessary for a base type or base interface to implement IDisposable if it's likely that code which expects an base-class instance might otherwise acquire ownership of an instance which requires disposal without realizing it. The most common scenario via which this may occur is with a factory method; a prime example is IEnumerable/IEnumerator. Most enumerators do not require cleanup, but code which calls IEnumerable.GetEnumerator generally has no particular reason to believe that the returned enumerator will actually require cleanup, nor to believe that it won't. It's generally faster to have all implementations of IEnumerator implement IDisposable, and have all consumers call Dispose on the returned enumerator, than to have consumers check whether the returned type implements IDisposable and call it if so.

If it is expected that base-type references will generally only be used by methods which will not be responsible for cleaning up the items in question, there is no need for the base type to implement IDisposable. The code which would be responsible for cleanup will know that the objects it's dealing with implement IDisposable whether or not the base type does.


Monday, August 20, 2018

AngularJs two ng-app module webpage

I am trying to figure a way to have my angular app use two modules. The main idea would be to separate login and the rest of the app. For that I need to override the module configuration. I simply don't want the user to be able to jump the login over to the normal app.

I am using angular.bootstrap following Working with two modules in AngularJS

 angular.bootstrap(document.getElementById('app'), ['app']);

This is how far I have come so far with the two modules. http://plnkr.co/edit/Euz6fK

Can someone help me?

Sunday, August 19, 2018

JDBC - java.sql.SQLException: ORA-00933: SQL command not properly ended

I am trying to execute the below query in Oracle DB through JDBC but its throwing an exception. The exception is:

java.sql.SQLException: ORA-00933: SQL command not properly ended

Please suggest what needs to be changed ?

String questionQuery = "SELECT PCN_SURVEY_DEFINITION.ID, PCN_SURVEY_DEFINITION.NAME, PCN_QUESTIONS.ID, PCN_QUESTIONS.SURVEY_ID, PCN_QUESTIONS.LABEL, "
                + "PCN_QUESTIONS.TYPE, PCN_QUESTIONS.REQUIRED, PCN_QUESTIONS.COMMENTS, PCN_QUESTIONS.DISPLAY_ORDER "
                + "FROM PCN_SURVEY_DEFINITION, PCN_QUESTIONS "
                + "WHERE PCN_SURVEY_DEFINITION.ID = PCN_QUESTIONS.SURVEY_ID "
                + "AND PCN_SURVEY_DEFINITION.NAME=? "
                + "ORDER BY PCN_QUESTIONS.DISPLAY_ORDER ASC"; 

Solved

Correct the condition in WHERE clause and check the quotes(") properly where to start and where to end.

"WHERE PCN_SURVEY_DEFINITION.ID = " + PCN_QUESTIONS.SURVEY_ID + " AND PCN_SURVEY_DEFINITION.NAME=? " + "ORDER BY PCN_QUESTIONS.DISPLAY_ORDER ASC";

What do you do with the question mark? Maybe you meant to put a column name here of the other table? The one before the ORDER BY? Or are you using a prepared statement afterwards? Try removing this condition temporarily for testing purposes: "AND PCN_SURVEY_DEFINITION.NAME=? "

 "WHERE PCN_SURVEY_DEFINITION.ID = PCN_QUESTIONS.SURVEY_ID " + "AND PCN_SURVEY_DEFINITION.NAME=? " + "ORDER BY 

Oracle does not suport question mark "?". For variable binding oracle uses ":name" or ":1"

https://docs.oracle.com/cd/B10501_01/appdev.920/a96584/oci05bnd.htm


I had something similar and had to add the following property in my application.properties file (since I am using Spring Boot), this resolved the issue for me without having to change any of my SQL

spring.jpa.database=oracle

Saturday, August 18, 2018

Saving multiple e-mails to pdf with PDFMAKER

I'm brand spanking new to VBA. But I've programmed a bit in SAS, just a bit in Assembler (mainframe and PC), Word Perfect (macros), a bit in Java, HTML, other stuff. What I do is, when I have a problem and I think I can program it, I look for code on the internet and adjust it to fit my needs. I have read a little bit of VBA programming. What I'm trying to do is make a macro to save a bunch of Outlook e-mail messages with PDFMAKER. I've come up with the below, so far. When I step the program, pmkr2 gets assigned type "ObjectPDFMaker" and stng gets assigned type "ISettings". So far, so good. Then I try to set stng and can't do it. I get the error "Method or data member not found." If I get rid of Set it highlights .ISettings and I get the same error. I go into F2 and the AdobePDFMakerforOffice library is there, and the class ISettings is there, but I can't seem to set stng. I'm wa-a-a-ay frustrated. Please help.

Sub ConvertToPDFWithLinks()

Dim pmkr2 As Object
Set pmkr2 = Application.COMAddIns.Item(6).Object ' Assign object reference.

Dim pdfname As String
pdfname = "C:\stuff\stuff\tester.pdf"

Dim stng As AdobePDFMakerForOffice.ISettings

Set stng = AdobePDFMakerForOffice.ISettings

stng.AddBookmarks = True
stng.AddLinks = True
stng.AddTags = True
stng.ConvertAllPages = True
stng.CreateFootnoteLinks = True
stng.CreateXrefLinks = True
stng.OutputPDFFileName = pdfname
stng.PromptForPDFFilename = False
stng.ShouldShowProgressDialog = True
stng.ViewPDFFile = False

pmkr.GetCurrentConversionSettings stng

pmkr2.CreatePDFEx stng, 0

Set pmkr2 = Nothing ' Discontinue association.

End Sub

Solved

I updated your code a little. See if this has any affect:

Sub ConvertToPDFWithLinks()
   Dim pmkr2 As AdobePDFMakerForOffice.PDFMaker
   'Set pmkr2 = Application.COMAddIns.Item(6).Object ' Assign object reference.
   Set pmkr2 = Nothing

   For Each a In Application.COMAddIns
      If InStr(UCase(a.Description), "PDFMAKER") > 0 Then
        Set pmkr2 = a.Object
        Exit For
      End If
   Next

   If pmkr2 Is Nothing Then
      MsgBox "Cannot Find PDFMaker add-in", vbOKOnly, ""
      Exit Sub
   End If

   Dim pdfname As String
   pdfname = "C:\stuff\stuff\tester.pdf"

   Dim stng As AdobePDFMakerForOffice.ISettings
   pmkr2.GetCurrentConversionSettings stng

   stng.AddBookmarks = True
   stng.AddLinks = True
   stng.AddTags = True
   stng.ConvertAllPages = True
   stng.CreateFootnoteLinks = True
   stng.CreateXrefLinks = True
   stng.OutputPDFFileName = pdfname
   stng.PromptForPDFFilename = False
   stng.ShouldShowProgressDialog = True
   stng.ViewPDFFile = False

   pmkr2.CreatePDFEx stng, 0

   Set pmkr2 = Nothing ' Discontinue association.
End Sub

The main changes were in how the addin is obtained and in how stng is created.