디버그 방법을 알고 싶습니다.

VScode에서 왼쪽 디버그메뉴 > 디버그 실행시 나오는 오류입니다. ㅠㅠ

Cannot start service from the command line or a debugger. A Windows Service must first be installed and then started with the ServerExplorer, Windows Services Administrative tool or the NET START command.

바로 아래 이부분 을 출력해보려고 디버그 포인트 찍어서 해본겁니다.
너무 지지분해서 죄송합니다.

var injectTypeList = Assembly.GetAssembly(initialType).GetTypes()
    .Where(t => t.CustomAttributes
        .Where(t2 => t2.AttributeType == typeof(InjectionAttribute)).Count() > 0);

소스코드

using Unity;
using Unity.Interception;
using Unity.Interception.ContainerIntegration;
using Unity.Interception.Interceptors.InstanceInterceptors.InterfaceInterception;
using System.Reflection;
using Serilog;
using System;
using System.Linq;
using IgsCommon.IOC.Attibutes;
using IgsCommon.Util.Helper;
using IgsCommon.Logger;
using Unity.Injection;
using IgsCommon.Handler.DB;
using System.Collections.Generic;
using IgsCommon.Handler.Rest;
using IgsCommon.Handler.File;

namespace IgsCommon.IOC
{
    /// <summary>
    /// Service 객체 생성과 DL을 담당하는 클래스
    /// </summary>
    /// <desc>
    /// 객체의 적재 단계는 지연된 시작이 아니라 어플리케이션 시작 단계에서 이루어져야 하기 때문에
    /// 싱글톤을 사용하지 않고 전역변수를 사용함
    ///
    /// - 커스터마이징 요건이 발생하였을 시
    ///     -> 커스터마이징 요건에 해당하는 서비스 클래스를 개발
    ///     -> 기존 서비스 대신 커스터마이징 서비스를 등록
    ///     -> 서비스를 교체하는 방식으로 커스터마이징 요건 대체
    /// </desc>

    public static class IOCContainer
    {
        private static ICommonLogger logger = IGSLoggerFactory.LOGGER;

        /// <summary>
        /// IOC Container 생성
        /// Creates a new extension object and adds it to the container.
        /// </summary>
        private static IUnityContainer CONTAINER = new UnityContainer().AddNewExtension<Interception>();

        /// <summary>
        /// web app 시작 시 IOC Container에 객체 삽입
        /// </summary>
        public static void Initialize(Type initialType)
        {
            CONTAINER.AddExtension(new Diagnostic());

            // 대표적인 타입을 기준으로 어셈블리 호출
            var injectTypeList = Assembly.GetAssembly(initialType).GetTypes()
                .Where(t =>
                    t.CustomAttributes.Where(t2 => t2.AttributeType == typeof(InjectionAttribute)).Count() > 0);

            foreach (var typeItem in injectTypeList)
            {
                // 사용자 정의 속성 조회
                var attr = typeItem.CustomAttributes.Where(t => t.AttributeType == typeof(InjectionAttribute)).SingleOrDefault();
                string serviceName = attr.NamedArguments.Where(na => na.MemberName == "ServiceName").SingleOrDefault().TypedValue.Value.Nvl();
                Type interfaceType = attr.NamedArguments.Where(na => na.MemberName == "InterfaceType").SingleOrDefault().TypedValue.Value as Type;
                Type interceptorType = attr.NamedArguments.Where(na => na.MemberName == "InterceptorType").SingleOrDefault().TypedValue.Value as Type;
                LifeCycle lifeCycle = (LifeCycle)attr.NamedArguments.Where(na => na.MemberName == "LifeCycle").SingleOrDefault().TypedValue.Value;
                var typeLifeTime = TypeLifetime.Singleton;

                switch (lifeCycle)
                {
                    case LifeCycle.Singleton:
                        typeLifeTime = TypeLifetime.Singleton;
                        break;
                    case LifeCycle.PerResolve:
                        typeLifeTime = TypeLifetime.PerResolve;
                        break;
                    case LifeCycle.PerThread:
                        typeLifeTime = TypeLifetime.PerThread;
                        break;
                    default:
                        break;
                }

                Console.WriteLine("인터셉트: " + interceptorType);

                // 객체 등록
                if (interceptorType == null)
                {
                    IOCContainer.CONTAINER.RegisterType(interfaceType, typeItem, serviceName, typeLifeTime);

                }
                else  
                {
                    var interceptorInf = new Interceptor<InterfaceInterceptor>();

                    IOCContainer.CONTAINER.RegisterType(interfaceType, typeItem, serviceName, typeLifeTime

                        , interceptorInf, new InterceptionBehavior(interceptorType));
                }
                logger.Write(EnumLogLevel.INFO, "Regist service = {0}", serviceName);
            }
        }

        internal static void SetDbHandler(DbConfig dbConfig)
        {
            string serviceName = string.Format("DB.{0}", dbConfig.InstanceName);

            IOCContainer.CONTAINER.RegisterType(
                typeof(SmartSqlHandler), serviceName
                , lifetimeManager: TypeLifetime.Singleton
                , new InjectionProperty("DbConfig", dbConfig));
            FindService<SmartSqlHandler>(serviceName).Init();
            logger.Write(EnumLogLevel.INFO, "Regist service = {0}", serviceName);
        }

        internal static void SetApiHandler(ApiServerConfig serverConfig)
        {
            string serviceName = string.Format("API_SERVER.{0}", serverConfig.ServerName);
            IOCContainer.CONTAINER.RegisterType(
                serverConfig.Type, serviceName
                , lifetimeManager: TypeLifetime.Singleton
                , new InjectionProperty("HostUrl", serverConfig.Url));
            logger.Write(EnumLogLevel.INFO, "Regist service = {0}", serviceName);
        }
        internal static void SetFileHandler(FileServerConfig serverConfig)
        {
            string serviceName = string.Format("FILE.{0}", serverConfig.ServerName);
            Type baseType = null;
            switch (serverConfig.Protocol)
            {
                case FileServerProtocol.FTP:
                    baseType = typeof(FtpFileHandler);
                    break;
                case FileServerProtocol.NTFS:
                    break;
                case FileServerProtocol.S3:
                    break;
                default:
                    break;
            }

            IOCContainer.CONTAINER.RegisterType(
                typeof(IFileHandler)
                , baseType
                , serviceName
                , lifetimeManager: TypeLifetime.Singleton
                , new InjectionProperty("Config", serverConfig));
            logger.Write(EnumLogLevel.INFO, "Regist service = {0}", serviceName);
        }

        /// <summary>
        /// 서비스를 호출하는 메서드
        /// </summary>
        /// <param name="serviceName">서비스 이름</param>
        /// <typeparam name="T">서비스의 추상객체 제네릭 타입</typeparam>
        /// <returns>서비스 추상객체</returns>
        public static T FindService<T>(string serviceName)
        {
            T retService;
            retService = CONTAINER.Resolve<T>(serviceName);
            return retService;
        }

        /// <summary>
        /// 서비스를 호출하는 메서드
        /// </summary>
        /// <returns>서비스 추상객체</returns>
        public static IEnumerable<T> FindServiceAll<T>()
        {
            IEnumerable<T> retService;
            retService = CONTAINER.Resolve<IEnumerable<T>>();
            return retService;
        }
    }
}
1 Like

오류 메시지대로 입니다;

2 Likes
  1. 윈도우 서비스 프로젝트를 (먼저 맞는지 확인 필요해요) Visual Studio 에서 디버그로 시작해서 특정 위치에 중단점으로 동작을 확인하는것은 안됩니다. 관련해서 윈도우 서비스 프로젝트를 어떻게 디버깅할 수 있는지 정성태님의 글을 공유 드렸었습니다.
  2. 가능하시면 윈도우 서비스 모듈과 동작 모듈을 분리해서 동작 모듈을 테스트 할 수 있는 환경을 구축하는 것을 추천합니다.
  3. 지금 진행하시는 일이 회사일이라면 코드를 생성한 개발자분께 도움을 요청하시는 것이 효율적인 것 같습니다. 만약 회사일이 아니라면 질문을 올리실 때 재현 가능한 소스코드를 같이 올려주시면 좋은 답을 얻으실 수 있습니다.
  4. 그리고 특별한 경우가 아니라면 (예를 들어 리눅스 환경에서 개발을 진행해야 한다던가) Visual Studio 환경으로 작업하는 것을 추천합니다. Visual Studio Code는 범용 개발환경이라 .NET, C# 개발은 Visual Studio가 좋습니다.
3 Likes

참고로, 소스코드를 공유 주실 때는

```csharp
코드
```

하면 깔끔하게 표시가 됩니다.

2 Likes