none
今WindowsForm上で呼び出されているかASP.NET上で呼び出されているかを判断したい。 RRS feed

  • 質問

  • お世話になります。

     

    C#でユーティリティ・メソッドを作成し、1つのDLLに固めています。

     

    それをクライアント側のWinFormでも、サーバ側のASP.NETでも使っています。

     

    そんな中、そのDLLの中のメソッドで、今WinFormで呼ばれているのかASP.NETで呼ばれているのかを判断できたらなと思っています。

     

    何か良い方法はありませんでしょうか?

    2007年8月1日 9:32

回答

  • 難しいですね。僕にはちょっと方法が思いつきません。

     

    しかし、気になったので・・・

     

    何のために判断させたいのでしょうか?

    もし、挙動を変えるために、という理由であるなら、それは設計を見直すべきかと思います。

     

    Windows.Forms によって利用されることを前提にした挙動をするのなら、HogeHoge.Windows.Forms のような名前空間下に置くべきで、ASP であるなら、HogeHoge.Web のような名前空間下に置くべきです。

    そして、どちらからも利用され、全く同じ挙動をするものならば、それは内部で判断させたいという考え方は起きないでしょう。

     

    まず、1つの DLL にまとめるということを再検討されてみては如何でしょうか?
    2007年8月1日 10:07
  • 今更って感じですが……。

    業務上どうしても呼び出し元を変更できないというのであれば、
    System.Web.HttpContext.Current を参照して判断するという荒業もあります。
    ただし、このプロパティはスレッド依存ですので、
    ASP.NET ページが、新しいスレッドを作成して呼び出す場合はダメです。

    もちろん、推奨される方法ではありませんが。

    // 何故、HttpContext.Current なんてプロパティがあるのだろうか

    2007年10月30日 16:52
  • コレもいまさらなんですが。。。

    typeからアセンブリを取り出し、そのパスをとる方法があります。

     

    typeof(対象のクラス).Assembly.Location

     

    2007年11月1日 13:35
  •  まみや さんからの引用

    そんな中、そのDLLの中のメソッドで、今WinFormで呼ばれているのかASP.NETで呼ばれているのかを判断できたらなと思っています。

     
    ASP.NET をホスティングする WindowsForm アプリケーションの上で動いてる場合とか、面倒なパターンもありそうですが。
     
    System.Web.Hosting.ApplicationManager.GetApplicationManager().GetRunningApplications() が長さ0の配列を返せば、ASP.NET アプリケーションではないことが確認できます。
    # これを呼ぶと ApplicationManager のインスタンスが生成されちゃうのが難点ですが
     
    不要なオブジェクトが生成されないが不完全な方法としては、スタックからアタリをつけるという手もあるでしょうけど、すでに書かれているように、ASP.NET の上で生成されたワーカースレッド上からの呼び出しにおいて、判断をあやまる可能性が高いですね。
     
    パスの基準をクラスライブラリ自信の位置を基準にするとか、外部から設定してもらうなどの設計の変更がベターかと思います。
     
    2007年11月2日 8:40

すべての返信

  • 難しいですね。僕にはちょっと方法が思いつきません。

     

    しかし、気になったので・・・

     

    何のために判断させたいのでしょうか?

    もし、挙動を変えるために、という理由であるなら、それは設計を見直すべきかと思います。

     

    Windows.Forms によって利用されることを前提にした挙動をするのなら、HogeHoge.Windows.Forms のような名前空間下に置くべきで、ASP であるなら、HogeHoge.Web のような名前空間下に置くべきです。

    そして、どちらからも利用され、全く同じ挙動をするものならば、それは内部で判断させたいという考え方は起きないでしょう。

     

    まず、1つの DLL にまとめるということを再検討されてみては如何でしょうか?
    2007年8月1日 10:07
  •  R・田中一郎 さんからの引用

    難しいですね。僕にはちょっと方法が思いつきません。

     

    しかし、気になったので・・・

     

    何のために判断させたいのでしょうか?

    もし、挙動を変えるために、という理由であるなら、それは設計を見直すべきかと思います。

     

    Windows.Forms によって利用されることを前提にした挙動をするのなら、HogeHoge.Windows.Forms のような名前空間下に置くべきで、ASP であるなら、HogeHoge.Web のような名前空間下に置くべきです。

    そして、どちらからも利用され、全く同じ挙動をするものならば、それは内部で判断させたいという考え方は起きないでしょう。

     

    まず、1つの DLL にまとめるということを再検討されてみては如何でしょうか?

     

    おっしゃる通りですね。デザインとしておかしいですよね。

     

     ちなみに、今回横着をしようとしていた内容は、相対パスから絶対パスに変換する処理なんですが、WindowsFormの場合、カレントディレクトリ(?)は(基本的には)Exeが置かれているフォルダで、絶対パスに変換するときは、そこを基点とすればよいと思っています。ところが、Webの場合は、カレントディレクトリがIISのモジュール(?)のフォルダで、絶対パスに変換するときは、Webのbinディレクトリを基点としたいと思っていまして、そのあたりを自動で分岐したいとたくらんでいました...。

     

     もう一度考え直してみたいと思います。

    2007年8月1日 11:12
  • 今更って感じですが……。

    業務上どうしても呼び出し元を変更できないというのであれば、
    System.Web.HttpContext.Current を参照して判断するという荒業もあります。
    ただし、このプロパティはスレッド依存ですので、
    ASP.NET ページが、新しいスレッドを作成して呼び出す場合はダメです。

    もちろん、推奨される方法ではありませんが。

    // 何故、HttpContext.Current なんてプロパティがあるのだろうか

    2007年10月30日 16:52
  • コレもいまさらなんですが。。。

    typeからアセンブリを取り出し、そのパスをとる方法があります。

     

    typeof(対象のクラス).Assembly.Location

     

    2007年11月1日 13:35
  •  まみや さんからの引用

    そんな中、そのDLLの中のメソッドで、今WinFormで呼ばれているのかASP.NETで呼ばれているのかを判断できたらなと思っています。

     
    ASP.NET をホスティングする WindowsForm アプリケーションの上で動いてる場合とか、面倒なパターンもありそうですが。
     
    System.Web.Hosting.ApplicationManager.GetApplicationManager().GetRunningApplications() が長さ0の配列を返せば、ASP.NET アプリケーションではないことが確認できます。
    # これを呼ぶと ApplicationManager のインスタンスが生成されちゃうのが難点ですが
     
    不要なオブジェクトが生成されないが不完全な方法としては、スタックからアタリをつけるという手もあるでしょうけど、すでに書かれているように、ASP.NET の上で生成されたワーカースレッド上からの呼び出しにおいて、判断をあやまる可能性が高いですね。
     
    パスの基準をクラスライブラリ自信の位置を基準にするとか、外部から設定してもらうなどの設計の変更がベターかと思います。
     
    2007年11月2日 8:40